SQL 是一种声明式语言 (Declarative Language),它只表达用户想要的是什么,具体怎么实现用户的目的则由数据库的优化器模块自行决定,即对查询选择相应的执行计划。对于同一条用户 SQL,在数据库中可能对应多种不同的实现方式,优化器面临的常见选择包括:
查询中的表访问是选择全表扫描,还是索引扫描,以及应该选择哪个索引。
查询中的 JOIN 操作应该选择什么 JOIN 顺序,以及每个 JOIN 应该选择什么 JOIN 算法。
查询中的 GROUP BY 和 ORDER BY 选择什么策略来实现。
查询中的子查询选择什么策略来处理。
这些选择会产生大量的组合结果,即候选执行计划,优化器会从这些候选执行计划中选择它认为最优的一个用于执行。
大部分情况下,优化器都能够选中执行效率较高的执行计划,但不可避免地在某些场景下,它不能选中最优执行计划,因为以下两个可能的原因:
优化器没能枚举到最优的那个候选执行计划。
优化器在评估所有候选执行计划时出现了偏差,最优执行计划没能胜出。
在这些场景下,如果优化器默认选择的执行计划执行效率很低,就需要 DBA 或者用户进行 SQL 调优,提升查询性能。
要做 SQL 调优,首先需要理解优化器选中的执行计划所代表的执行逻辑,从中识别出执行开销高的那部分,进而分析为什么优化器会这样选择,然后干涉优化器对执行计划的选择,使得期望中更好的执行计划能被选中。