create table on_test (
 id varchar(10),
 name varchar(20),
 sex varchar(20)
)engine=innodb;CREATE INDEX aaid ON on_test(id);-- 现在插入数据 insert into no_test(id,name,sex) values('0','MM','f');
--             ..
--             insert into no_test(id,name,sex) values('99','MM','f');-- 一共100 行 , id是自增的. id从0 到 99-- 现在执行以下语句root@localhost [test_op]> explain select id,name from on_test where id>='0' and id<='24';
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table   | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | on_test | range | aaid          | aaid | 13      | NULL |   18 | Using where |
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+ 
root@localhost [test_op]> explain select id,name from on_test where id>='0' and id<='25';
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | on_test | ALL  | aaid          | NULL | NULL    | NULL |  100 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+-- 当查询小于等于25%的数据时,完全可以用到index ,当查询大于25%时用不到index-- 在看另一个实验-- 还是原来这个表 和 索引 -- 但在现在把数据改成10000行 id还是自增的 id 从1 到 10000-- 结果如下:root@localhost [test_op]> explain select id,name from on_test where id>='1' and id <='1999';
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table   | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | on_test | range | aaid          | aaid | 13      | NULL | 1110 | Using where |
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+root@localhost [test_op]> explain select id,name from on_test where id>='1' and id <='2000';
+----+-------------+---------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows  | Extra       |
+----+-------------+---------+------+---------------+------+---------+------+-------+-------------+
|  1 | SIMPLE      | on_test | ALL  | aaid          | NULL | NULL    | NULL | 10495 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+-------+-------------+-- 当查询小于20%的数据时,完全可以用到index ,当查询大于20%时用不到index
-- 我想问的是:
-- 1.mysql在使用index时,第一个实验为什么可以在25%的范围内用index,而第二个实验却只能在20%的范围内使用呢?-- 2.那随了数据量的增加,使用index的范围也会主键减小吗? 那当数据非常大的时候,这个index不成废物了..-- 3.我知道出现这种情况是,mysql认为全表扫描比使用index快,才去使用全表扫描的.
--   拿第1个实验来说.
--   扫描索引树只需要26行,再通过聚簇也只需要扫描26行就可以拿出数据了 一共只需要扫描52行.怎么会认为比全表慢呢....?
 

解决方案 »

  1.   

    把 id varchar(10) 改成id integer
      

  2.   


    只谈index..我建主键干嘛。这是对index做实验....
      

  3.   

    是否使用扫描取决于是否最好的索引跨越超过30%的表。优化器更加复杂,其估计基于其它因素,例如表大小、行数和I/O块大小,因此固定比例不再决定选择使用索引还是扫描。 
     正用常量值比较索引列,并且MySQL已经计算到(基于索引树)常数覆盖了表的很大部分并且表扫描将会比较快你正通过另一个列使用一个低的集的势的关键字(许多行匹配关键字)。在这种情况下,MySQL假设通过使用关键字它可能会进行许多关键字查找,表扫描将会更快。
      

  4.   


    INNODB下,如果指定了主键,那么就使用这个主键,如果没有指定主键,那么会用一个非空字段作为默认的主键字段。所以这个表里的ID列是个内含的主键。
      

  5.   

    楼主的这个例子有点小BUG,字段类型是字符的,当数字来比较大小,得到的值是不准确的。这能解释为什么第一个查询得到的是18行,而不是25行。MYSQL的执行计划的是根据“开销”来计算的。比如一个查询能够产生100个执行计划,MYSQL内部比较每个执行计划的“开销”,哪个的开销小,就用谁。
      

  6.   

    是MYSQL随机选择?强制使用索引试试,应该是MYSQL自行判断不使用索引要快一些