为什么Mysql在一个简单的between中使用索引下推(ICP)?

问题

今天在一个组里, 有人问了这么一个问题. img_7.png

一个简单的表: t, innodb引擎, 三个字段

  1. id 主键
  2. a 有索引
  3. b 有索引

一个简单的sql: select * from where a between 1000 and 2000;

为什么会在explain里出现, Using index condition.

疑惑点

因为按照我网上学来的经验, 索引下推是这么解释的: Mysql性能优化:什么是索引下推? 好像是, where里面要有两个条件,还要联合索引才能使用.

一开始我是想, 是不是因为 between and 算是两个条件, a>1 and a<2 之类..就试了下

create table t(
    id int,
    a int,
    b int,
    primary key(id),
    key a(a),
    key b(b)
  
  )

当我改掉sql, 换成了普通的 explain select * from t where a >1; 获取到的结果, 仍然是

id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	filtered	Extra
1	SIMPLE	t	NULL	range	a	a	5	NULL	1	100.00	Using index condition

就是说哪怕where里只有一个条件, 仍然是可以ICP的. 所以, 估计是上面的教程不靠谱. 我就换了个文档.

读了什么是索引下推 这个文档后, 答案就比较清晰了..

作者首先指出, 索引下推这四个字, 是一个错误翻译, 最基本的, 他漏译了Condition这个字. Index Condition Pushdown这句话的意思是, 索引条件下推.

然后是一段官方文档的翻译

ICP is used for the range, ref, eq_ref, and ref_or_null access methods when there is a need to access full table rows.

这里的条件是一个range查询, select *需要获取完整行的数据. 可不就刚刚好符合了icp发动 所需要的条件, range+获取整行.

这篇文最有收获的, 其实是这个配图.

img_8.png

查了下, 出自 http://blog.163.com/li_hx. 可惜网易博客已经关门了..

走时光机找到了, 作者叫 “那海蓝蓝”. 微博还在 数据库专家,现在在腾讯. 感觉可以买本出的书看 数据库查询优化器的艺术 (豆瓣)

另外,从豆瓣评价里拉到一本 Molina与Ullman等人所著杨冬青译第二版《数据库系统实现》 回头再看吧.先mark.

经验教训

少看二手文档, 特别是不知道作者是谁的情况下, 很可能他是瞎抄的. 知名作者的可以考虑. 我去买书了..