why mysql cann't using index to filter column after range condition ; mysql 5.1.40 os:rhel 5.4 engine=innodb innodb_file_per_table # create table use test; drop table index_test; create table index_test (id bigint(20) unsigned NOT NULL AUTO_INCREMENT , col1 varchar(255), col2 varchar(255), col3 datetime, col4 varchar(255), primary key (id), key (col1,col3,col2) ) engine=innodb charset=utf8; # Insert data for c1 in $(seq -w 500 ) do col1="username"$c1 for c2 in $(seq -w 500 ) do col2="othercol"$c2 col3=$(date +"%Y-%m-%d %H:%M:%S" -d "${c1} hour ago") mysql -uroot -h127.0.0.1 test -e "insert into index_test values (null,'${col1}','${col2}','2010-06-03 00:00:00' - interval $c2 hour,'${col1}${col2}'); commit;" done done ###--- test.sql1 ================================================ reset query cache; show session status like 'Innodb_buffer_pool_read_requests'; select count(*) from index_test where col1='username014' and col3 >= '2010-05-01 00:00:00' and col3 <= '2010-06-03 00:00:00' ; show session status like 'Innodb_buffer_pool_read_requests'; ## result : 500 ## Innodb_buffer_pool_read_requests: 77 ## well done , all search in index ; +----+-------------+------------+-------+---------------+------+---------+------+------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+---------------+------+---------+------+------+--------------------------+ | 1 | SIMPLE | index_test | range | col1 | col1 | 777 | NULL | 656 | Using where; Using index | +----+-------------+------------+-------+---------------+------+---------+------+------+--------------------------+ root@127.0.0.1 : test 16:25:52> show profile for query 1; +--------------------------------+----------+ | Status | Duration | +--------------------------------+----------+ | starting | 0.000023 | | checking query cache for query | 0.000068 | | Opening tables | 0.000025 | | System lock | 0.000004 | | Table lock | 0.000024 | | init | 0.000035 | | optimizing | 0.000014 | | statistics | 0.000083 | | preparing | 0.000013 | | executing | 0.000005 | | Sending data | 0.000655 | | end | 0.000004 | | query end | 0.000002 | | freeing items | 0.000037 | | storing result in query cache | 0.000004 | | logging slow query | 0.000001 | | cleaning up | 0.000002 | +--------------------------------+----------+ ###--- test.sql2 ================================================ reset query cache; show session status like 'Innodb_buffer_pool_read_requests'; select count(*) from index_test where col1='username014' and col3 >= '2010-05-01 00:00:00' and col3 <= '2010-06-03 00:00:00' #### and col2 = 'dsdlfkj' ; show session status like 'Innodb_buffer_pool_read_requests'; ## result : 0 ## Innodb_buffer_pool_read_requests: 77 ## well done , all search in index ; +----+-------------+------------+-------+---------------+------+---------+------+------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+---------------+------+---------+------+------+--------------------------+ | 1 | SIMPLE | index_test | range | col1 | col1 | 777 | NULL | 656 | Using where; Using index | +----+-------------+------------+-------+---------------+------+---------+------+------+--------------------------+ root@127.0.0.1 : test 16:26:25> show profile for query 2; +--------------------+----------+ | Status | Duration | +--------------------+----------+ | starting | 0.000041 | | Opening tables | 0.000031 | | System lock | 0.000002 | | Table lock | 0.000005 | | init | 0.000007 | | optimizing | 0.000002 | | statistics | 0.000006 | | preparing | 0.000005 | | executing | 0.000114 | | Sending data | 0.000015 | | end | 0.000003 | | query end | 0.000001 | | freeing items | 0.000015 | | removing tmp table | 0.000005 | | closing tables | 0.000001 | | logging slow query | 0.000001 | | cleaning up | 0.000001 | +--------------------+----------+ 17 rows in set (0.00 sec) ###--- test.sql3 ================================================ reset query cache; show session status like 'Innodb_buffer_pool_read_requests'; select count(distinct col4 ) from index_test where col1='username014' and col3 >= '2010-05-01 00:00:00' and col3 <= '2010-06-03 00:00:00'; show session status like 'Innodb_buffer_pool_read_requests'; ## result : 500 ## Innodb_buffer_pool_read_requests: 1550 +----+-------------+------------+-------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | index_test | range | col1 | col1 | 777 | NULL | 656 | Using where | +----+-------------+------------+-------+---------------+------+---------+------+------+-------------+ root@127.0.0.1 : test 16:27:27> show profile for query 6; +--------------------------------+----------+ | Status | Duration | +--------------------------------+----------+ | starting | 0.000020 | | checking query cache for query | 0.000071 | | Opening tables | 0.000010 | | System lock | 0.000002 | | Table lock | 0.000016 | | init | 0.000025 | | optimizing | 0.000011 | | statistics | 0.000060 | | preparing | 0.000009 | | executing | 0.000029 | | Sending data | 0.002875 | | end | 0.000004 | | removing tmp table | 0.000004 | | end | 0.000001 | | query end | 0.000002 | | freeing items | 0.000021 | | storing result in query cache | 0.000003 | | logging slow query | 0.000001 | | cleaning up | 0.000001 | +--------------------------------+----------+ ###--- test.sql4 ================================================ reset query cache; show session status like 'Innodb_buffer_pool_read_requests'; select count(distinct col4 ) from index_test where col1='username014' and col3 >= '2010-05-01 00:00:00' and col3 <= '2010-06-03 00:00:00' #### and col2 = 'dsdlfkj' ; show session status like 'Innodb_buffer_pool_read_requests'; ## result : 0 ## Innodb_buffer_pool_read_requests: 1542 +----+-------------+------------+-------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | index_test | range | col1 | col1 | 1545 | NULL | 656 | Using where | +----+-------------+------------+-------+---------------+------+---------+------+------+-------------+ root@127.0.0.1 : test 16:27:58> show profile for query 8 ; +--------------------------------+----------+ | Status | Duration | +--------------------------------+----------+ | starting | 0.000017 | | checking query cache for query | 0.000048 | | Opening tables | 0.000009 | | System lock | 0.000003 | | Table lock | 0.000017 | | init | 0.000027 | | optimizing | 0.000012 | | statistics | 0.000065 | | preparing | 0.000009 | | executing | 0.000028 | | Sending data | 0.001245 | | end | 0.000004 | | removing tmp table | 0.000014 | | end | 0.000003 | | query end | 0.000001 | | freeing items | 0.000027 | | storing result in query cache | 0.000004 | | logging slow query | 0.000001 | | cleaning up | 0.000002 | +--------------------------------+----------+ 19 rows in set (0.00 sec) ## It's so Bad , col2 can't filter by index ; ## Mysql find all record (fileted col1 , col3 ) from table , then filter the col2='dsdlfkj'. ## As we think , test.sql4 should not to researh record from table , because result=0; ## That can be know while using index;