SQL Server中TOP的巨大性能下滑

NKC*_*CSS 5 t-sql sql-server-2005

考虑这个SQL性能差异,在第一个中,我选择所有26,000行,而在第二个中,我只想要前5个.

SELECT tw.*
FROM entity e
JOIN entity_tag et on et.entity_id = e.id
JOIN tag t on t.tag_id = et.tag_id
JOIN tagrelatedtweets trt on trt.FK_Tag_ID = t.tag_id
JOIN tweets tw on tw.PK_Tweet_ID = trt.FK_Tweet_ID
WHERE e.id = 765131
ORDER BY tw.[timestamp]
Run Code Online (Sandbox Code Playgroud)

VS

SELECT TOP (5) tw.*
FROM entity e
JOIN entity_tag et on et.entity_id = e.id
JOIN tag t on t.tag_id = et.tag_id
JOIN tagrelatedtweets trt on trt.FK_Tag_ID = t.tag_id
JOIN tweets tw on tw.PK_Tweet_ID = trt.FK_Tweet_ID
WHERE e.id = 765131
ORDER BY tw.[timestamp]

Without: CPU =    201 | Reads:    6880 | Writes:    0 | Duration:   451
With:    CPU = 302439 | Reads: 7453199 | Writes: 3169 | Duration: 74188
Run Code Online (Sandbox Code Playgroud)

这对我来说没有意义......还有另一种方法可以解决这个问题吗?

在Martin提出所有相关表格的REBUILD统计数据之后,有一个小的改进,但将TOP数量更改为参数的技巧效果最好.

在统计重建之前:

CPU = 302439 | Reads: 7453199 | Writes: 3169 | Duration: 74188 
Run Code Online (Sandbox Code Playgroud)

统计重建后:

CPU = 127734 | Reads: 4100436 | Writes: 2656 | Duration: 16880 
Run Code Online (Sandbox Code Playgroud)

带参数:

CPU =    218 | Reads:    6899 | Writes:    0 | Duration:    83 
Run Code Online (Sandbox Code Playgroud)

查询参数:

DECLARE @TOP INT; SET @TOP=5; 
SELECT TOP (@TOP) tw.*
FROM entity e
JOIN entity_tag et on et.entity_id = e.id
JOIN tag t on t.tag_id = et.tag_id
JOIN tagrelatedtweets trt on trt.FK_Tag_ID = t.tag_id
JOIN tweets tw on tw.PK_Tweet_ID = trt.FK_Tweet_ID
WHERE e.id = 765131
ORDER BY tw.timestamp desc
Run Code Online (Sandbox Code Playgroud)

对于那些使用Entity Framework的人来说,最后一句话; 如果您遇到此行为,您可以模拟相同的基于参数的行为,如下所示:

.Take(100).ToList().Take(5)
Run Code Online (Sandbox Code Playgroud)

我知道它并不漂亮,但如果你使用的是实体框架,那么这是触发正确执行计划的唯一方法.

非常感谢Martin指出我正确的方向!

Mar*_*ith 3

根据评论中的讨论,似乎出于某种原因,SQL Server 选择针对“仅前 5 行”情况进行优化的计划并不是最优的。它可能会使用非阻塞运算符(例如嵌套循环连接),而不是阻塞运算符(例如哈希连接)。

由于您无法发布执行计划,因此很难确切地知道原因,但是比较两个版本的查询的计划并查看问题查询的实际执行计划中的实际行数与估计行数应该会有所帮助。就此事。

在这种情况下,TOP 5在编译时向优化器隐藏信息似乎足以为您提供您想要的计划!