UNION ALL可以比JOIN快,还是我的JOIN只是吮吸?

Jos*_*son 4 t-sql sql-server-2008

我有一个Notes带有uniqueidentifier列的表,我用它作为数据库中各种其他表的FK(不用担心,uniqueidentifier其他表上的列不是集群PK).这些其他表表示业务对象层次结构的某些内容.作为一个简单的表示,假设我还有另外两个表:

  • 潜在客户(PK LeadID)
  • 行情(PK QuoteID,FK LeadID)

Lead应用程序中显示a 时,我需要显示与潜在客户相关的所有注释,包括标记为任何Quote属于该潜在客户的注释.据我所知,我有两个选择 - 一个UNION ALL或几个LEFT JOIN语句.这是他们看起来的样子:

SELECT N.*  
FROM Notes N  
JOIN Leads L ON N.TargetUniqueID = L.UniqueID  
WHERE L.LeadID = @LeadID

UNION ALL

SELECT N.*  
FROM Notes N  
JOIN Quotes Q ON N.TargetUniqueID = Q.UniqueID  
WHERE Q.LeadID = @LeadID 
Run Code Online (Sandbox Code Playgroud)

要么...

SELECT N.*  
FROM Notes N  
LEFT JOIN Leads L ON N.TargetUniqueID = L.UniqueID  
LEFT JOIN Quotes Q ON N.TargetUniqueID = Q.UniqueID  
WHERE L.LeadID = @LeadID OR Q.LeadID = @LeadID
Run Code Online (Sandbox Code Playgroud)

在现实生活中,我总共有五个表可以附加注释,并且随着应用程序的增长,这个数字可能会增长.我已经在uniqueidentifier我正在使用的列上设置了非聚集索引,而SQL Profiler说我无法进行任何更多改进,但是当我对实际大小的测试数据集进行性能测试时,我得到以下内容数字:

  • UNION ALL - 0.010秒
  • LEFT JOIN - 0.744秒

我一直听说使用UNION不好,而且UNION ALL只是稍微好一点,但性能数字似乎并没有表现出来.当然,UNION ALLSQL代码可能更难以维护,但在这种性能差异下,它可能是值得的.

所以UNION ALL在这里真的更好,还是我在LEFT JOIN代码上遗漏了一些让事情变慢的东西?

Mar*_*ith 6

这个UNION ALL版本很可能很容易被2个索引寻求满足.OR可以导致扫描.执行计划是什么样的?

您是否尝试过此操作以避免访问Notes两次?

;WITH J AS
(
SELECT UniqueID FROM Leads WHERE LeadID = @LeadID
UNION ALL
SELECT UniqueID FROM Quotes WHERE LeadID = @LeadID
)

SELECT N.*  /*Don't use * though!*/
FROM Notes N  
JOIN J ON N.TargetUniqueID = J.UniqueID  
Run Code Online (Sandbox Code Playgroud)