SQL性能优化
越前须知(雾)
- 本系列参考《SQL进阶教程》1,DBMS选用MySQL。
- 本系列不涉及数据库安装与基础语句,对初学者存在一定门槛;基础知识建议阅读《SQL必知必会(第四版)》与《SQL基础教程(第二版)》。
- 本篇主题为HAVING子句进阶用法,基础用法见同系列前文。
概述
- 使用高效的查询
- 避免排序
- 使用索引
- 减少中间表
使用高效的查询
- 参数是子查询时,用EXISTS代替IN
- 参数是子查询时,用连接代替IN
避免排序
涉及排序的运算:
- GROUP BY
- ORDER BY
- 聚合函数(SUM、COUNT、AVG、MAX、MIN)
- DISTINCT
- 集合运算符(UNION、INTERSECT、EXCEPT)
- 窗口函数(RANK、ROW_NUMBER、DENSE_RANK)
避免排序的方法:
- 若结果允许重复,使用 UNION ALL 而不是 UNION
- 用 EXISTS 代替 DISTINCT
- 在极值函数中使用索引(MAX/MIN)
- 在 GROUP BY 和 ORDER BY 子句中使用索引
使用索引
- 在索引字段上进行运算
- 使用联合索引(col_1, col_2, col_3)时,必须从联合索引中第一列开始,且索引中位置不能颠倒(位置颠倒后性能变差)
- 使用 Like 谓词时,只有前方一致的匹配才能用到索引,如 ‘a%’,类似’%a%’、’%a’均不行
减少中间表
频繁使用表会导致两个问题:
- 展开数据需要耗费内存资源
- 原始表中的索引不容易被使用(特别是聚合时)
减少中间表的方法:
- 对多个字段使用 IN 谓词时,将它们汇总到一处,如 CONCAT(A, B) 比用两个 IN 子查询性能好
- 合理使用视图,若视图中存在大量聚合函数、集合运算符,整体语句性能差
MICK[日] 《SQL进阶教程》 ↩︎