慢查询的怀疑方向

  • 索引设计有问题
  • SQL语句有问题
  • 数据库选错索引

    覆盖索引

  • 查询语句从执行到返回结果均使用同一个索引

  • 覆盖索引通过取消回表操作,提升查询效率
  • 可以通过优化SQL语句或优化联合索引,来使用覆盖索引

    索引基数

  • 根据索引基数,可以判断索引性能的好坏

  • 使用force index可以强制使用索引

    count()函数

  • count(非索引字段):无法使用覆盖索引,最慢

  • count(索引字段):可以使用覆盖索引但依然要取出数据判空
  • count(1):不需要取出数据,但需要判断“1是否为null”
  • count(*):经过专门优化,不需要判空,理论最快

    ORDER BY

  • MySQL排序一般需要生成中间结果集、排序、回表的过程

  • 索引覆盖是最高效的处理排序的方式

    随机选取

  • 临时优化:使用SQL语句选出随机主键

  • 业务优化:使用业务选出随机偏移量,再用分页查询语法

    索引下推

  • MySQL5.6之后,如果索引中可以判断,直接使用索引过滤

    松散索引扫描

  • 松散索引扫描可以打破“左侧原则”,解决带头大哥丢失的问题

    字段做函数操作

  • MySQL中,对索引字段做函数操作,优化器会放弃索引

  • 这种情况可能包括:时间函数,字符串转数字,字符编码转换
  • 解决方案:时间函数转区间、数字强转字符串、高级编码转低级

    分页查询

  • 排序偏移量大时,会丢弃大量无用数据,导致效率低下

  • 可以采取先索引覆盖,再用最终ID回表的方法,优化效率