1. 概述
这一章是上一章索引的延续,主要讲到了覆盖索引、联合索引、最左前缀、索引下推等概念,为了让我们在复杂业务场景下,更合理的使用索引。
2. 总结
2.1 覆盖索引
覆盖索引就是如果查询条件使用的是普通索引(或是联合索引的最左原则字段),查询结果是联合索引的字段或是主键,不用回表操作,直接返回结果,减少IO磁盘读取整行数据。
但是索引字段的维护总是有代价的。因此,在建立冗余索引来支持覆盖索引时就需要权衡考虑了。
2.2 联合索引
联合索引就是多个字段一起作为普通索引进行创建。
根据创建联合索引的顺序,以最左原则进行where检索,比如 (age, name) 以age=1 或 age= 1 and name=‘张三’可以使用索引,单以name=‘张三’ 不会使用索引,所以需要单独创建一个name的普通索引。
这时就出现了两种选择,一种是 (age, name) 及 (name) 的组合,一种是 (name, age) 及 (age) 的组合。我们需要考虑到存储空间的问题,如果 name 字段是比 age 字段大的,建议创建一个 (name, age) 的联合索引和一个 (age) 的单字段索引。
2.3 最左前缀
联合索引的最左 N 个字段,也可以是字符串索引的最左 M 个字符。
2.4 索引下推
MySQL 5.6 引入的索引下推优化(index condition pushdown), 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。
比如:like 'hello%’and age >10 检索,MySQL5.6版本之前,会对匹配的数据进行回表查询。5.6版本后,会先过滤掉age<10的数据,再进行回表查询,减少回表率,提升检索速度。
2.5 思考题:关于对联合主键索引和 InnoDB 索引组织表的理解
表记录
–a--|–b--|–c--|–d--
1 2 3 d
1 3 2 d
1 4 3 d
2 1 3 d
2 2 2 d
2 3 4 d
主键 a,b 的聚簇索引组织顺序相当于 order by a,b ,也就是先按 a 排序,再按 b 排序,c 无序。
索引 ca 的组织是先按 c 排序,再按 a 排序,同时记录主键
–c--|–a--|–主键部分b-- (注意,这里不是 ab,而是只有 b)
2 1 3
2 2 2
3 1 2
3 1 4
3 2 1
4 2 3
这个跟索引 c 的数据是一模一样的。
索引 cb 的组织是先按 c 排序,在按 b 排序,同时记录主键
–c--|–b--|–主键部分a-- (同上)
2 2 2
2 3 1
3 1 2
3 2 1
3 4 1
4 3 2
所以,结论是 ca 可以去掉,cb 需要保留。
InnoDB会把主键字段放到索引定义字段后面, 当然同时也会去重。 所以,当主键是(a,b)的时候, 定义为c的索引,实际上是(c,a,b); 定义为(c,a)的索引,实际上是(c,a,b) 你看着加是相同的 ps 定义为(c,b)的索引,实际上是(c,b,a)。