版本:SQL Server 2014 Enterprise。
我有一个复杂的查询,该查询返回3 integer columns - 428 rows in total
。其中一些行是重复的(所有3列都匹配)。结果以 millisecs 返回。
如果我使用SQL distinct
关键字,它将以 7秒为代价返回2行的正确结果。
如果我使用CTE
在DISTINCT
中将原始查询的执行计划与CTE
隔离开-仍然是 7秒。为什么?
如果我将428 rows of results
放在3列的空表中并运行select distinct c1, c2, c3 from newtable
,我将在milliseconds
中获得正确的2行。
所以我的问题是:
DISTINCT
会根本改变执行计划,为什么在查询的所有其他方面都完成之后不仅仅处理行? 2-如何在没有millisecs
的情况下在DISTINCT
中用SQL区分结果?
附录:原始查询无明显区别:
SELECT
coopterm0_.id AS x0_0_, coopterm0_.jobPostingTerm AS x1_0_,
coopterm0_.currentJobSearchTerm AS x2_0_
FROM
coop_term coopterm0_,
np_posting nposting1_
WHERE
(coopterm0_.jobPostingTerm = nposting1_.term)
AND (nposting1_.status IN (4, 6))
AND (nposting1_.term IS NOT NULL)
AND (nposting1_.term IN (391, 392, 393, 410, 411, 412, 413, 415, 416 ))
AND ((( nposting1_.dateLastSaved >= '2019-01-20 16:00:00')
OR (EXISTS (SELECT napplication2_.id
FROM np_application napplication2_
WHERE (napplication2_.job = nposting1_.id)
AND (napplication2_.dateApplied >= '2019-01-20 16:00:00')))
OR (EXISTS (SELECT npostingview3_.id
FROM np_posting_view npostingview3_
WHERE (npostingview3_.posting = nposting1_.id)
AND (npostingview3_.dateViewed >= '2019-01-20 16:00:00')))))
运行这两个命令将执行时间减少到2秒,但仍慢了1000倍,而没有明显差异:更新统计信息np_posting_view WITH FULLSCAN;使用fullscan更新统计信息np_application;
不同的执行计划(慢):brentozar.com/pastetheplan/?id=BkQrhRXm4不明显(快速):brentozar.com/pastetheplan/?id=HJYdnA7mE
答案 0 :(得分:0)
首先使用变量代替常量来测试您的查询。它给出了更真实的执行计划,并提供了实际执行计划。
IMO,您的查询未正确编写,因此Optimizer无法创建恒定或更好的计划来执行查询。
在CTE或Distinct情况下,不清楚查询内容,因为这取决于查询条件。
您必须注意到np_posting nposting1_
的谓词在您的一个查询中正在多次评估。
原因之一是由于Bracket
。查询中的括号组错误。
括号影响Optimizer
评估Predicate
的方式。
如果np_posting nposting1
的结果集很小,则将它们放在CTE
中,否则将它们放入Temp
表中。
如何在不使用DISTINCT的情况下以毫秒为单位区分SQL中的结果?
您可以避免使用Distinct运算符,因为不同运算符的成本始终很高。
Distinct operator
:首先获取所有行,然后消除重复的行。
Group BY
:它将从头开始删除重复的行。
尝试一下,
DECLARE @Date datetime='2019-01-20 16:00:00'
With CTE AS(
SELECT term ,id
FROM np_posting nposting1_
WHERE ( nposting1_.status IN(4, 6)
AND
nposting1_.term IS NOT NULL AND nposting1_.term IN ( 391, 392, 393, 410, 411, 412, 413, 415, 416 )
AND nposting1_.dateLastSaved >= @Date )
OR
( EXISTS ( SELECT napplication2_.id FROM np_application napplication2_ WHERE napplication2_.job = nposting1_.id
AND napplication2_.dateApplied >= @Date ) )
OR
( EXISTS ( SELECT npostingview3_.id FROM np_posting_view npostingview3_
WHERE npostingview3_.posting = nposting1_.id AND npostingview3_.dateViewed >= @Date ) )
)
SELECT coopterm0_.id AS x0_0_, coopterm0_.jobPostingTerm AS x1_0_, coopterm0_.currentJobSearchTerm AS x2_0_
FROM coop_term coopterm0_
inner join CTE nposting1_
on coopterm0_.jobPostingTerm = nposting1_.term
group by coopterm0_.id,coopterm0_.jobPostingTerm,coopterm0_.currentJobSearchTerm