【发布时间】:2012-06-06 10:56:40
【问题描述】:
我有这个问题...
SELECT Distinct([TargetAttributeID]) FROM
(SELECT distinct att1.intAttributeID as [TargetAttributeID]
FROM AST_tblAttributes att1
INNER JOIN
AST_lnkProfileDemandAttributes pda
ON pda.intAttributeID=att1.intAttributeID AND pda.intProfileID = @intProfileID
union all
SELECT distinct ca2.intAttributeID as [TargetAttributeID] FROM
AST_lnkCapturePolicyAttributes ca2
INNER JOIN
AST_lnkEmployeeCapture ec2 ON ec2.intAdminCaptureID = ca2.intAdminCaptureID AND ec2.intTeamID = 57
WHERE ec2.dteCreatedDate >= @cutoffdate) x
Execution Plan for the above query
两个内部不同的分别查看 32 和 10,000 行。此查询返回 5 行并在 1 秒内执行。
如果我随后使用此查询的结果作为 IN 的主题...
SELECT attx.intAttributeID,attx.txtAttributeName,attx.txtAttributeLabel,attx.txtType,attx.txtEntity FROM
AST_tblAttributes attx WHERE attx.intAttributeID
IN
(SELECT Distinct([TargetAttributeID]) FROM
(SELECT Distinct att1.intAttributeID as [TargetAttributeID]
FROM AST_tblAttributes att1
INNER JOIN
AST_lnkProfileDemandAttributes pda
ON pda.intAttributeID=att1.intAttributeID AND pda.intProfileID = @intProfileID
union all
SELECT Distinct ca2.intAttributeID as [TargetAttributeID] FROM
AST_lnkCapturePolicyAttributes ca2
INNER JOIN
AST_lnkEmployeeCapture ec2 ON ec2.intAdminCaptureID = ca2.intAdminCaptureID AND ec2.intTeamID = 57
WHERE ec2.dteCreatedDate >= @cutoffdate) x)
Execution Plan for the above query
然后需要 3 多分钟!如果我只是获取查询结果并“手动”执行IN,那么它会很快返回。
但是,如果我删除两个内部 DISTINCTS....
SELECT attx.intAttributeID,attx.txtAttributeName,attx.txtAttributeLabel,attx.txtType,attx.txtEntity FROM
AST_tblAttributes attx WHERE attx.intAttributeID
IN
(SELECT Distinct([TargetAttributeID]) FROM
(SELECT att1.intAttributeID as [TargetAttributeID]
FROM AST_tblAttributes att1
INNER JOIN
AST_lnkProfileDemandAttributes pda
ON pda.intAttributeID=att1.intAttributeID AND pda.intProfileID = @intProfileID
union all
SELECT ca2.intAttributeID as [TargetAttributeID] FROM
AST_lnkCapturePolicyAttributes ca2
INNER JOIN
AST_lnkEmployeeCapture ec2 ON ec2.intAdminCaptureID = ca2.intAdminCaptureID AND ec2.intTeamID = 57
WHERE ec2.dteCreatedDate >= @cutoffdate) x)
Execution Plan for the above query
..然后它会在一秒钟内恢复。
SQL Server 在想什么?难道它不知道它可以执行两个子查询并将结果用作IN 的主题。它看起来和相关子查询一样慢,但它不相关!!!
在 Show Estimate Execution 计划中有三个聚集索引扫描,每个扫描的成本为 100%! (执行计划为here)
谁能告诉我为什么内部的DISTINCTS 让这个查询慢得多(但只有在用作IN 的主题时...)?
更新
抱歉,我花了一段时间才制定这些执行计划......
【问题讨论】:
-
如果您发布 XML 计划(供下载),您将获得更好的响应
-
因此,在将其与
IN子查询一起使用时,请删除DISTINCT。问题解决了:) -
你是怎么写这篇文章的——为什么你要自己做 3 次不同的工作,而只是切换到
union(从union all会自动执行该操作)?跨度> -
我认为这更适合dba.stackexchange.com,你可能会在那里得到更好的答案。您可以将其标记为迁移。
-
实际执行计划而不是估计计划会更好,并且对于查询(第 2 次和第 3 次)
标签: sql-server query-optimization