索引分类
-
通常索引分类:普通索引、唯一索引、全文索引、空间索引(老版本InnoDB引擎可能不支持后两者)
-
按存储方式分类:B-Tree、Hash(InnoDB不支持Hash)
B-Tree存储的所有数据是有序的!每个叶子和根距离相同。InnoDB使用的是B+树,NDB使用的是T树。
-
按依赖列数分类:单列索引、组合索引
-
按数据分布分类:聚簇索引、二级索引(辅助索引)
聚簇索引末级即叶子直接存储了数据行,通常的主键索引就是聚簇索引。
-
按回表情况分类:覆盖索引
当一个索引包含(覆盖)了需要查询的字段的值时,就称其为覆盖索引。
- 聚簇索引包含了所有的数据,所以它也是一个覆盖索引,这个说法是错的。只有select、where中出现的列被索引覆盖的情况才是覆盖索引,此时Extra会显示Using index
最左前缀
-- 一个表T,索引有abc三个
table T, index(a, b, c)
-- 以下代码中x代表某数据
-- 全值匹配
select * from T where a='xx' and b='xx' and c='xx'; -- 可以走索引
select * from T where c='xx' and b='xx' and a='xx'; -- 可以走索引,引擎会优化
-- 匹配左前缀
select * from T where a='x'; -- 可以走索引
select * from T where b='x'; -- 不可以走索引,不可一跳列
-- 匹配列前缀
select * from T where a like 'x%'; -- 可以走索引
select * from T where a like '%x'; -- 不可以,要从开头匹配
select * from T where b like 'x%'; -- 不可以,不可以跳列
-- 匹配范围值
select * from T where a between 'x' and 'x'; -- 可以走索引
select * from T where b between 'x' and 'x'; -- 不可以,不可以跳列
-- 全值匹配 + 范围匹配
select * from T where a='x' and b between 'x' and 'x'; -- 可以走索引
select * from T where b='x' and c between 'x' and 'x'; -- 不可以
select * from T where a between 'x' and 'x' and b='x'; -- 不可以
- 例如有一个表有L、F、B三个列,都是该表的索引,按照从左到右列的索引排序则为下表所示。
如图为按索引排序的数据,先精确匹配在范围匹配。
例如:当我们查找记录(行)L1、F3、B3时,按照索引搜索就如下图所示。