慢SQL查询的排查解决
1. 排查问题方向
从索引、架构、网络、I/O吞吐量、内存、锁、SQL语句等各个方向去分析。由于设计范围广,如果不理清思路逐步分析,便会使得排查效率极低。针对这个问题需要有个全局监控,然后再分情况分析。
大多数情况下正常,偶尔很慢:
可能是数据库正在刷新脏页,例如redo log需要同步到磁盘;或者执行的时候遇到了锁;或者SQL语句有问题,由于真是场景数据量大导致速度极慢;当然这是我们主要考虑的方向,也有其它原因:当时网络卡顿;内存不足;I/O数量太大等情况,当然一般公司都不太可能出现这种情况。
某个SQL一直执行慢:
可能没用上索引或索引失效(例如:查询的字段没有建索引;对索引字段运算或函数操作;)我们有了大概方向之后就可以结合具体手段去定位
慢查询排查方法:
慢查询日志(my.ini 设置慢查询时间、慢查询日志记录);执行计划(explain);show processlist;
explain需要关注的字段:type();key;key_len;possible_keys;extra(useing index:覆盖索引,不回表;useing filesort:不能通过索引排序,需要额外排序);
2. 优化方向
索引、SQL语句、数据库结构优化、优化器优化、架构优化、I/O、内存、网络
索引:
建立索引时就要考虑,一般建在where、order by,建立索引的条件,数据基数大、区分度高、不过度索引,避免索引失效,尽可能覆盖索引,5.6可以支持索引下推可以使的速度更快;写多读少的场景可以考虑用普通索引代替唯一索引,因为更新时可以使用change buffer进行优化,减少磁盘IO(将更新操作记录到change buffer等查询来了将数据读到内存再进行修改)
SQL语句调优举例:
1. limit 分页,limit 20000, 10修改成where id>20000 limit 10;2.insert 多条时写成一条,可以利用主键索引特性让数据有序插入时效率提高;SQL写法优化:union、union all;注意临时表、视图等等;
数据库结构:
1.冷热分离;2.经常联合的表建中间表或字段冗余;
架构:
分库分表(横向拆分、纵向拆分);读写分离;集群;
其它:
把数据、索引、日志文件放到不同的 I/O 设备上,增加读写速度;提升硬件、网速等;