- 遍历整个主键索引的B+树,并且需要读叶子节点数据,称为全表扫描。遍历整个非聚集索引的B+树,称为全索引扫描。
模式 |
分析参数 |
值 |
描述 |
全表扫描 |
type |
all |
通过读物理表获取数据,顺序读磁盘上的文件。这种情况会顺序读磁盘上的文件 |
全索引扫描 |
type |
index |
查询时,遍历索引树来获取数据行。如果数据不是密集的会产生随机IO |
范围索引 |
type |
range |
一个有范围限制的索引扫描,它开始于索引里的某一点,返回匹配这个范围值的行 |
索引合并 |
type |
index_merge |
优化器会尝试合并单个索引为一个多列索引,利用索引索引列 |
索引覆盖 |
extra |
using index |
如果where条件的列和返回的数据在一个索引中,可以直接使用索引 |
- index 与 ALL 区别为 index 类型只遍历索引树,通常比 ALL 快,因为索引文件通常比数据文件小。一个是遍历整个索引,一个是遍历整张表。
示例
EXPLAIN -- 全表扫描,不走ID索引
SELECT * FROM users;
运行结果如下:
示例
EXPLAIN -- 全索引扫描,走ID索引
SELECT id FROM users;
运行结果如下:
示例
EXPLAIN -- 范围索引
SELECT id FROM users WHERE id > 3;
运行结果如下:
示例
EXPLAIN -- 索引合并,单个索引合并为多列索引
SELECT name, age FROM users WHERE name = '张三' OR age < 15;
运行结果如下:
示例
EXPLAIN -- 索引覆盖,查询使用多列索引(name, age)
SELECT name, age FROM users WHERE name LIKE '张%' AND age = 20;
运行结果如下:
- 全索引扫描并不一定就比全表扫描好,取决于数据存储位置。如果数据在内存,那么这两种没有太大区别。如果数据在磁盘,全表扫描比全索引扫描要好,这是因为,全表扫描是顺序读数据(顺序IO),而全索引扫描是随机读取数据(随机IO),可能会产生随机读(reandom read)。显然,顺序读要比随机读快很多
注
- unique_subquery 和 index_subquery 虽然都存在使用索引优化,但默认情况下,MySQL 优化器会对查询语句优化,会被优化,因此不会在分析结果中显示,只有在非 SELECT 语句下会显示