Dr Milan Milanović整理的20条SQL查询优化关键技巧,涵盖索引策略、查询写法、执行计划选择等核心要点,帮助提升数据库性能与响应速度:
1. 根据查询访问模式设计索引,优先复合索引、选择性高的列和覆盖索引,保持统计信息最新,避免仅按行数建索引。
2. 用EXISTS判断存在性,只有真正需要计数时才用COUNT(*)。
3. 明确列名,避免SELECT *,减少I/O并更好利用覆盖索引。
4. 优先使用SARGable(可利用索引)的谓词,复杂相关子查询改写为JOIN或EXISTS。
5. 避免用DISTINCT修复错误连接,应先检查连接条件和主键,只有确实去重时才用。
6. 条件过滤放WHERE,HAVING只在聚合后过滤。
7. 使用显式JOIN ... ON,避免在WHERE中隐式连接。
8. 大数据分页用键集分页(keyset pagination),避免OFFSET/LIMIT;采样用TABLESAMPLE(若支持)。
9. 当允许重复时,UNION ALL代替UNION以提升性能。
10. 用UNION ALL替代宽泛的OR谓词,前提是每个分支能利用不同索引。
11. 重负载查询安排在非高峰时段,必要时设置资源限制或排队机制。
12. 避免在连接条件中用OR,改用计算列或UNION ALL以利用索引。
13. 需要分组时用GROUP BY,若要细节和聚合共存则用窗口函数。
14. 派生表或临时表能减少工作量或增加统计信息时使用,注意避免阻塞优化。
15. 批量加载时禁用/删除非聚集索引,分批插入后重建索引,保留主键和聚集索引。
16. 慢变且昂贵的聚合用物化视图,加上合理的刷新策略。
17. 避免低选择性列上的非SARGable比较(如<>),尽量改写为范围查询。
18. 尽量减少大集合上的相关子查询,优先用集合型JOIN或EXISTS。
19. 根据语义选INNER或LEFT/RIGHT JOIN,INNER通常性能更优。
20. 缓存重复查询结果:会话临时表、结果缓存或物化视图,并制定刷新规则。
SQL查询优化器的核心任务是为给定查询生成多种执行计划,计算各自成本(磁盘读写、CPU时间等),选择最低成本方案执行。它通过解析语法树、分析多种执行路径,自动决定最佳访问顺序、连接方法及过滤排序策略。
优化器虽强大,但SQL调优仍是“艺术”,依赖具体数据库、数据分布、硬件资源和业务场景。掌握这些技巧,结合实际环境灵活应用,才能真正提升性能。
原文链接:x.com/milan_milanovic/status/1979160597620031733
