对于我尝试优化的中等复杂查询,我注意到删除TOP n子句会更改执行计划。我猜想,当查询包含TOP n数据库引擎时,会运行查询而忽略该TOP子句,然后最后将结果集缩小到请求的n行数。图形执行计划似乎表明情况确实如此——TOP是“最后”一步。但似乎还有更多事情发生。
我的问题是,TOP n 子句如何(以及为什么)影响查询的执行计划?
这是我的情况的简化版本:
查询匹配来自两个表 A 和 B 的行。
如果没有该TOP子句,优化器估计将有来自表 A 的 19k 行和来自表 B 的 46k 行。返回的实际行数是 A 的 16k 和 B 的 13k。哈希匹配用于连接这两个结果集总共 69 行(然后应用排序)。此查询发生得非常快。
当我添加TOP 1001优化器时不使用哈希匹配;相反,它首先对表 A 的结果进行排序(与 19k/16k 相同的估计值/实际值)并对表 B 执行嵌套循环。表 B 的估计行数现在为 1,奇怪的是TOP n直接影响对 B 的估计执行次数(索引搜索) - 它似乎总是2n+1,或者在我的情况下是 2003 年。如果我改变,这个估计会相应地改变TOP n。当然,由于这是嵌套连接,因此实际执行次数为 16k(表 A 中的行数),这会减慢查询速度。
实际场景有点复杂,但这捕获了基本思想/行为。两个表都使用索引查找进行搜索。这是 SQL Server 2008 R2 企业版。
performance sql-server optimization execution-plan query-performance
我有一个具有复杂逻辑和三个深度级别(嵌套视图)的视图。由于复杂,我无法粘贴执行计划。
由于视图的目的是向数据分析师提供一些业务分析,而他们正在开发报告时,他们会通过执行选择(前 N 个)查询来检查视图样本。
视图中的这个(前 N 个)查询执行得非常糟糕,因为优化器正在为此视图选择不同的执行计划(afaik CQScanTopSortNew)
我尝试对顶部 (N) 用例进行一些优化,例如使用哈希连接,但这会破坏非顶部 (n) 用例。
非顶级 (n) 表现良好。我想知道如何防止优化器在具有 top (n) 子句时选择不同的执行计划,而不会显着改变视图的结构或功能。
例如,如果我在视图中添加一个 select distinct ,优化器总是会选择正确的计划,但视图的功能会发生变化。
sql-server execution-plan sql-server-2016 performance-tuning