SQL优化核心是降低磁盘IO和减少扫描行数,需结合执行计划(type/key/rows/Extra)、索引设计(最左前缀、避免冗余)及SQL写法(LIMIT、拆分查询、避免SELECT *)系统治理。
SQL优化的核心目标之一,是降低磁盘IO和减少扫描行数——这两项直接决定查询响应时间与系统吞吐能力。从运维视角看,不合理的SQL往往在高并发或大数据量场景下迅速暴露为慢查询、IO瓶颈甚至主从延迟。优化不是单纯改写SQL,而是结合执行计划、索引设计、数据分布和业务语义做系统性判断。
运维人员排查慢SQL的第一步,永远是EXPLAIN(或EXPLAIN FORMAT=JSON)。重点关注四项:
ALL意味着全表扫描,必须干预;index虽走索引但仍是全索引扫描,同样需警惕。Using filesort(排序未走索引)、Using
temporary(临时表)、Using where(非索引字段参与过滤)等提示,它们常伴随额外IO开销。运维中常见误区是“给WHERE里所有字段都建索引”。有效索引需满足最左前缀原则,并覆盖高频过滤+排序+分组需求:
>、BETWEEN)后字段无法被索引利用,应把范围条件放复合索引最后。ORDER BY中,且无Using filesort,说明索引已包含有序路径,例如INDEX (a,b,c)可支持WHERE a=1 ORDER BY b,c。(a,b),再建(a)意义不大;定期用sys.schema_unused_indexes(MySQL 8.0+)或慢查日志反向验证索引使用率。很多扫描膨胀源于SQL逻辑本身,无需改表结构也能见效:
LIMIT限制结果集,尤其分页场景:避免OFFSET过大(如LIMIT 10000,20仍要扫前10020行),改用游标分页(记录上一页最大ID)。JOIN + GROUP BY + ORDER BY + LIMIT大查询,拆成子查询先定位主键,再回表取详情,显著减少中间结果集大小。Using temporary on disk),大幅增加IO。优化不能只靠DBA单点发力,需与开发、测试形成闭环:
EXPLAIN结果,重点检查rows是否超阈值(如单次扫描>1万行)。Rows_examined排序,优先处理“扫描行数/返回行数”比值异常高的SQL。innodb_stats_persistent=ON并定期ANALYZE TABLE,避免统计信息过期导致执行计划劣化。