[mysql,innodb] 一个简单的sql语句为何没有使用索引?

新手上路,请多包涵

mysql ,innodb, 版本 5.1.73 , RR隔离级别

表结构如下:
表 news结构:
CREATE TABLE news (
id bigint(20) NOT NULL COMMENT 'id',
number bigint(20) NOT NULL COMMENT 'number',
tmp bigint(20) NOT NULL COMMENT 'tmp',
PRIMARY KEY (id),
KEY number (number),
KEY tmp (tmp)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='测试';

insert into news(id,number,tmp) values(1,2,600);
insert into news(id,number,tmp) values(6,5,400);
insert into news(id,number,tmp) values(8,5,300);
insert into news(id,number,tmp) values(10,5,500);
insert into news(id,number,tmp) values(13,11,100);

数据A:
图片描述

数据B:

图片描述

数据B比数据A多了一条记录,
insert into news(id,number,tmp) values(3,4,200);
但是执行这个sql的时候却没有使用索引
select * from news where number>2 for update;
图片描述
请问是为什么呢?

阅读 3.4k
2 个回答

任何基于索引的db在查询的时候都有一个代价的计算,根据索引检索数据的过程是先检索索引表找到满足你条件的索引值部分,再根据这部分列数据指向的位置去检索你要的索引列以外的数据,如果你只取索引列数据的话取多少数据都会走索引的,这就是索引覆盖扫描
但是如果你的查询本来就是要取表的大部分数据,对于db来说就没有必要先去检索一遍索引再去根据检索到的索引列检索相应的表数据,这样反而检索的总数据量更多,稍微智能点的优化器都会选择直接扫描全表的。

尽管查询条件带索引,但未必会用到,这取决于索引的区分度。像您这种情况,number > 2会把所有数据都取出来,所以区分度很差。

另外,没有WHERE到主键的话,无论是否命中索引都会锁全表的。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题