背景
在调试数据库时发现一个比较奇怪的现象:
有表table_a:
查看执行计划:
现在是有走索引,只不过是扫描全部索引。
改动一下这个表,新增一个普通字段。
再看一下执行计划:
可以看到现在变成全表扫描了
原因
- 先明白几个概念:
- 主键索引:叶子节点保存数据。
- 辅助索引:叶子节点保存主键值。
- 数据查询过程:上述,如果使用辅助索引获取到数据就必须先从辅助索引取到主键的值,再使用主键的值去主键索引上查询,直到找到叶子节点上的数据返回。这个过程也叫
回表
。
- 索引覆盖:如果辅助索引上已经存在我们需要的数据,那么引擎就不会拿主键回表取数据了。
- 一开始我们的表中所有的字段都创建了索引,所以无论怎么查(包括 * 号查询),都属于是索引覆盖,但会有全索引扫描;当我们又向表中新增一个没有索引的普通字段,再用 * 号查询时,就会触发回表,所以就会有全表扫描。
- 所以通常说的避免星号查询的原因之一也是为了避免回表。
扩展
条件:C='a'
条件:B='b' and C='a'
条件:A='b' and C='a'
,左前缀原则,从A字段断点,C字段没走索引。
条件:B='b' and C='a'