我有一个 Notes
表,其中有一个 uniqueidentifier
列,我将其用作数据库中各种其他表的 FK(不用担心,其他表上的 >uniqueidentifier
列不是集群 PK)。这些其他表代表了业务对象的某种层次结构。作为一个简单的表示,假设我还有另外两个表:
- 潜在客户(PK LeadID)
- 报价(PK QuoteID、FK LeadID)
在应用程序中显示Lead
时,我需要显示与该潜在客户相关的所有注释,包括标记到属于该潜在客户的任何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
或者...
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
在现实生活中,我总共有五个可以附加注释的表,并且这个数字可能会随着应用程序的增长而增长。我已经在我正在使用的 uniqueidentifier
列上设置了非聚集索引,SQL Profiler 说我无法进行任何更多改进,但是当我对实际大小的性能测试时测试数据集,我得到以下数字:
UNION ALL
— 0.010 秒LEFT JOIN
— 0.744 秒
我一直听说使用 UNION
很糟糕,而 UNION ALL
只是稍微好一点,但性能数据似乎并不能证明这一点。诚然,UNION ALL
SQL 代码维护起来可能比较麻烦,但考虑到这种性能差异,它可能是值得的。
那么,UNION ALL
在这里真的更好吗?还是我在 LEFT JOIN
代码中遗漏了一些会减慢速度的东西?
最佳答案
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
关于t-sql - UNION ALL 可以比 JOIN 更快吗?还是我的 JOIN 很糟糕?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3374459/