3个关键点:
- 执行计划
- 索引
- 查询中每步的查询集大小
我的SQL调优步骤:
1. 发现慢查询后,分析其执行计划
2. 合理建立索引,再次分析测试
3. 如果经过1、2依然对性能不满意,写出所有可能的查询SQL,分别按照1、2处理;
4. 根据1、2、3,使用实际数据,权衡后选择最佳的SQL
(红色标注的是关键,艺术在于平衡)
注意大数据记录的表查询,首要原则不一定是利用索引,往往从减少每步SQL查询结果集能得到更好地性能。
就我经历的几次系统调优中,就遇到了几个突破常理的:
案例:
1页面数据显示需要大约8分钟才能出来;
优化过程:分析页面慢的原因是一个SQL查询(多表、分组统计)太慢,通过分析执行计划看到确实全部使用了索引,老大说这个无法再优化了。
我写出所有可能的SQL,然后一个个测试,最后使用了in的查询方式,测试结果大吃一惊,只需要不到300ms。从此后遇到sql性能问题时,我记住了这个原则——写出所有可能的查询SQL,实际测试
开发时需要注意的:实际数据才能检验你写的SQL真理,不要过早优化SQL,先尽量写最简单易读的SQL;
大数据记录的表往往in的查询方式性能更高,in时也要注意distinct和数据库的内部id(如oracle的rowid),往往可以得到意想不到的性能。
案例:
1用户关键业务过程,每天需要执行一次、有新档案时也需要执行。利用1个存储过程扫描历史记录已决定是否需要初始化某些区域内的客户档案数据,执行耗时大约5分钟:
优化过程:
1. 看懂存储过程:因为是外包做的,当时也没有文档,痛苦痛苦再痛苦,业务复杂,存储过程大约“不到”400行,那个难看阿,看懂后无非就是判断某些数据不存在,就初始化,如果已存在了,就根据条件修改某些值。
2. 写可能SQL:这已经是最简单可读的,要我写也只能写成这样。只好从性能调优入手,我把数据查询,大量使用子查询来减少每步的SQL结果集,最终存储过程代码近700行,可读性降低了,不过性能上去了,实测不到30s即可执行完毕。
实践才是检验的唯一标准,穷举自己所知道的,一个一个实地检测