t-sql - UNION ALL 可以比 JOIN 更快吗?还是我的 JOIN 很糟糕?

标签 t-sql sql-server-2008

我有一个 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/

相关文章:

sql - 选择上方或下方有附加行的结果

SQL Server 触发器将 "false"替换为 null

tsql - 重复删除

c# - 在显示特定产品时,电子商务网站更可取的是什么?

sql - SQL存储过程在转换参数时出现错误,文字没有错误

sql - 如何使用备份文件(.bak)生成数据库脚本

sql - 按记录分组,然后从每组中获取最后一个升序排序记录?

c# - 如何格式化存储过程以映射 EF 对象和自定义数据

c# - 在 SQL Server 中使用数组

sql-server - 将数据表保存到数据库