Gre*_*g R 4 sql-server execution-plan sql-server-2012 top
我有按月临时表的产品销售。(更大的历史表的子集)我正在运行查询以查找在指定的 6 个月范围内之前几个月未售出的新产品。因此,以 1 月为基础,在 2 月向我展示所有未在 1 月销售中销售的新产品。3 月所有未售出的新产品 1 月或 2 月销售等。前 5 个月查询返回次秒。第 6 个月,大约需要 5 分钟。比较执行计划,在第 6 个月,它显示我的执行计划中的 Top 运算符花费了额外的时间。但我没有在选择中排序或使用 Top X。我的查询中是什么导致了这种情况?我可以等 5 分钟,因为它是一次性请求,但我更多是从学习的角度询问,我想了解它为什么添加到 Top 运算符。提前致谢。
select divn_nbr, dept_nbr, vendorNumber, pid, nrfcolorNumber, periodcode
from ##tmpSFA a
where periodCode = '201512'
and not exists
(
select 1 from ##tmpSFA b
where ISNULL(a.divn_nbr, -99) = isnull(b.divn_nbr, -99)
and isnull(a.dept_nbr, -99) = isnull(b.dept_nbr, -99)
and isnull(a.vendorNumber, -99) = isnull(b.vendorNumber, -99)
and isnull(LTRIM(rtrim(upper(a.pid))), -99) = isnull(LTRIM(rtrim(upper(b.pid))), -99)
and isnull(a.nrfcolorNumber, -99) = isnull(b.nrfColorNumber, -99)
and b.periodCode IN ('201507', '201508', '201509', '201510', '201511')
)
Run Code Online (Sandbox Code Playgroud)
以下是结果和计划:
NOT EXISTS
可以引入一个TOP 1
(EXCEPT
在某些情况下可以)。这是因为它只关心至少存在一行这一事实。这称为短路,您需要这样 - 它更有可能加速您的查询而不是减慢查询速度。如果TOP
没有出现在不同日期范围的计划中,我会感到非常惊讶,除非行数存在显着差异并且编制了不同的计划。也许您可以将两个 .sqlplan 文件张贴在某处,以便我们可以将每个计划与查询相关联,并帮助确定任何差异的原因。有了屏幕截图和据称随之而来的查询,没有什么可以继续的。
我不相信TOP
你的情况是让这个查询运行 5 分钟。而不是仅仅查看计划,我实际上会调查查询在运行 5 分钟内在做什么,通过查看sys.dm_exec_requests
- 是否阻塞?什么是等待类型?由于您使用的是 ##global 临时表(为什么?),这可能是由于阻塞,但仅从计划的屏幕截图中就不清楚了。为什么您的##temp 表没有聚集索引?它还有哪些其他索引?将TOP
可能会更有效,如果它可以排序的东西明智除了全表扫描的输出。TOP (1) ... ORDER BY
有关更多信息NOT EXISTS
和替代方案,请参阅此博客文章。