MySQL where 范围查询和 order by 关键字无法同时命中索引
开发中,使用 in 和 order by 的时候,发现无法同时命中索引。
使用 IN 运算符来过滤行时,MySQL 会先使用索引来定位表中的行,并将这些行的所有数据读入内存中。随后,MySQL 会根据查询语句中的 ORDER BY 子句对这些数据进行排序。
简单场景构造
| |
Explain SELECT
非范围查询
| |
能够完美命中索引。
范围查询
| |
范围查询用到了filesort,表示 order by没有命中索引,abc 索引的作用相当于 ab。
索引分析
索引结构
| a | b | c |
|---|---|---|
| 1 | 1 | 1 |
| 2 | ||
| 3 | ||
| 2 | 1 | |
| 2 | ||
| 3 | ||
| 3 | ||
| 2 | 2 | 2 |
| 3 | 3 | 3 |
| |
在非范围查询的时候,可以发现,经过where语句,c的范围是 1、2、3,b已确定,c 有序,order by 可以命中索引。
| |
在范围查询的时候,经过where语句,c的范围是 1、2、3、1、2、3、3,b无法确定(可能为1或2),c 为无序,order by 无法命中索引。