相关疑难解决方法(0)

TOP 如何(以及为什么)影响执行计划?

对于我尝试优化的中等复杂查询,我注意到删除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

36
推荐指数
2
解决办法
1万
查看次数

Order By 导致对大表进行扫描

我有以下查询;

SELECT TOP 100 ID
FROM [dbo].[TableName] WITH (NOLOCK)
WHERE TypeId = 2
    AND DateTimeUTC < '2022-Aug-04 07:02:40'
    AND DateTimeUTC > '4/26/2022 7:36:36 AM'
ORDER BY ID ASC
Run Code Online (Sandbox Code Playgroud)

表 [dbo].[TableName](顺便说一句,不是它的真实名称)有超过 1.18 亿行。

我在此表上创建了以下索引;

CREATE INDEX [ix_TableName_DateTimeUTC_TypeId] 
ON [dbo].[TableName] (DateTimeUTC, TypeId)
    WITH FILLFACTOR = 90;
Run Code Online (Sandbox Code Playgroud)

如果我运行此查询(不包括ORDER BY),该查询会对上述索引执行 SEEK,并立即完成。然而,一旦我包含ORDER BY,查询就会在 PK 上执行 SCAN,读取所有 118+ 百万行。正如您可以想象的那样,这会降低性能并且查询需要很长时间才能完成。

解决此问题的最简单方法是完全删除该ORDER BY子句,但我认为这是不可能的,因为应用程序(进行此调用)要求按顺序返回数据。

关于如何改进这一点有什么建议吗?

sql-server index-tuning query-performance

14
推荐指数
4
解决办法
6021
查看次数