回表
是什么
回表是指在使用非聚簇索引作为条件进行查询时,由于索引中只存储了索引字段的值和对应的主键值,无法得到其他值,如果需要其他数据就需要根据主键去聚簇索引查找数据行,这个过程被称为回表。
产生的问题
回表会带来随机I/O,多次回表会导致效率降低。
优化措施
覆盖索引:查询的结果都可以从索引中得到,不需要从表里读取,避免了回表
索引下推:先返回第一个条件符合的索引,然后根据第二个条件判断索引是否符合条件。如果符合,则根据该索引来定位数据,如果不符合,则直接拒绝。这样就减少了回表次数。
减少不必要的查询字段
怎么挑选列去创建索引
选择合适的列
- 数据重复少的列
- 频繁用于查询条件的列
- 长字符串类型考虑使用前缀索引
控制索引的数量
- 每张表要控制索引的数量,索引过多会影响写入速度。
- 创建联合索引,要把常用的、区分度高的列放在左边
维护索引
- 定期重建或优化
- 添加新索引前,先在测试环境进行测试
排查索引效果
使用索引但不一定会生效。
- 使用联合索引,但是不符合最左原则
- 查询条件中索引使用了运算或函数
- 使用
like进行'%xxx%'查询 - 使用or,但是其中一个字段没有索引或者使用不当
- 数据类型的隐式转换
- 根据MySQL的成本评估,例如表数据量不大的情况下,会选择全表扫描
- 表里不同字段进行比较
order by后面的字段没有索引或者使用不当
如何排查
在查询语句前使用explain命令。重点观察type列(访问类型),通常会显示index或range,表示查询使用了索引,但是如果显示了all,则表示进行了全表扫描,没使用索引;key列(使用的索引),会显示使用的索引名称,如果显示null,则表示没使用索引;rows列(扫描的行数)。
