弗雷德里克·尤埃尔:被低估的合并连接节点的奇怪案例
内容提要
文章讨论了客户在批处理后首次执行查询时速度缓慢的问题。分析显示,查询计划在两次执行中不同,主要由于连接策略变化:首次使用合并连接,第二次使用嵌套循环连接。尽管表未清理或分析,优化器行为仍不同,导致执行时间差异。最后,作者提供了重现此现象的脚本。
关键要点
-
客户在批处理后首次执行查询时速度缓慢,第二次执行速度快。
-
查询计划在两次执行中不同,首次使用合并连接,第二次使用嵌套循环连接。
-
尽管表未清理或分析,优化器行为仍不同,导致执行时间差异。
-
首次执行的查询计划中,合并连接的成本高达145百万,而合并连接的实际成本仅为16,980。
-
直方图显示两个连接列之间没有重叠,导致优化器在首次执行时选择了不准确的估算。
-
在第二次执行时,优化器能够获取实际极值,从而选择了嵌套循环连接。
-
提供了重现此现象的脚本,创建两个表并禁用自动清理。
-
通过插入和删除数据,验证了直方图的重叠情况和优化器的选择变化。
-
结论是查询计划可以在两次执行之间变化,尽管数据和统计信息保持不变。
延伸解读
查询计划变化的原因
文章中提到,查询计划在两次执行中发生变化,主要是由于连接策略的不同。首次执行使用合并连接,而第二次则使用嵌套循环连接。这种变化的原因在于优化器在首次执行时未能获取准确的极值,导致选择了不合适的连接策略。了解这一点有助于开发者在优化查询时,关注统计信息的准确性。
优化器行为的影响
尽管表未进行清理或分析,优化器的行为依然不同,导致执行时间差异。这表明在处理大数据量时,优化器的选择可能会受到数据分布和直方图的影响。开发者应注意在批处理后及时更新统计信息,以避免潜在的性能问题。
重现现象的脚本价值
文章提供了重现查询计划变化现象的脚本,这对于数据库管理员和开发者来说非常有价值。通过实际操作,可以更深入地理解优化器的决策过程,从而在实际应用中更有效地优化查询性能。
延伸问答
为什么客户在批处理后首次执行查询时速度慢?
首次执行查询时使用了合并连接,导致成本高达145百万,而实际成本仅为16,980。
查询计划在两次执行中有什么不同?
首次执行使用合并连接,第二次执行使用嵌套循环连接,导致执行时间差异。
如何重现首次执行查询慢的现象?
可以通过创建两个表并禁用自动清理,插入数据并验证直方图的重叠情况来重现。
优化器在首次执行时为何选择了不准确的估算?
因为两个连接列之间没有重叠,导致优化器选择了不准确的估算。
在第二次执行时,优化器是如何选择连接策略的?
第二次执行时,优化器能够获取实际极值,从而选择了嵌套循环连接。
文章的结论是什么?
查询计划可以在两次执行之间变化,尽管数据和统计信息保持不变。