有一个“OR”在 INNER JOIN 条件下是一个坏主意吗?
在尝试提高极其缓慢的查询的速度时(如果重要的话,在 SQL Server 2008 上,在两个表上每个只有约 50,000 行的表上需要几分钟),我将问题范围缩小到 OR
在我的内部连接中,如下所示:
SELECT mt.ID, mt.ParentID, ot.MasterID
FROM dbo.MainTable AS mt
INNER JOIN dbo.OtherTable AS ot ON ot.ParentID = mt.ID
OR ot.ID = mt.ParentID
我将其更改为(我希望的是)一对等效的左连接,如下所示:
SELECT mt.ID, mt.ParentID,
CASE WHEN ot1.MasterID IS NOT NULL THEN
ot1.MasterID ELSE
ot2.MasterID END AS MasterID
FROM dbo.MainTable AS mt
LEFT JOIN dbo.OtherTable AS ot1 ON ot1.ParentID = mt.ID
LEFT JOIN dbo.OtherTable AS ot2 ON ot2.ID = mt.ParentID
WHERE ot1.MasterID IS NOT NULL OR ot2.MasterID IS NOT NULL
.. 现在查询运行大约一秒钟!
在连接条件中放置 OR
通常是一个坏主意吗?或者我只是在桌子的布局上不走运?
In trying to improve the speed of an immensely slow query (several minutes on two tables with only ~50,000 rows each, on SQL Server 2008 if it matters), I narrowed down the problem to an OR
in my inner join, as in:
SELECT mt.ID, mt.ParentID, ot.MasterID
FROM dbo.MainTable AS mt
INNER JOIN dbo.OtherTable AS ot ON ot.ParentID = mt.ID
OR ot.ID = mt.ParentID
I changed this to (what I hope is) an equivalent pair of left joins, shown here:
SELECT mt.ID, mt.ParentID,
CASE WHEN ot1.MasterID IS NOT NULL THEN
ot1.MasterID ELSE
ot2.MasterID END AS MasterID
FROM dbo.MainTable AS mt
LEFT JOIN dbo.OtherTable AS ot1 ON ot1.ParentID = mt.ID
LEFT JOIN dbo.OtherTable AS ot2 ON ot2.ID = mt.ParentID
WHERE ot1.MasterID IS NOT NULL OR ot2.MasterID IS NOT NULL
.. and the query now runs in about a second!
Is it generally a bad idea to put an OR
in a join condition? Or am I just unlucky somehow in the layout of my tables?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这种
JOIN
无法针对HASH JOIN
或MERGE JOIN
进行优化。它可以表示为两个结果集的串联:
,每个结果集都是一个等值连接,但是,
SQL Server
的优化器不够智能,无法在您编写的查询中看到它(尽管它们在逻辑上是相等的)。This kind of
JOIN
is not optimizable to aHASH JOIN
or aMERGE JOIN
.It can be expressed as a concatenation of two resultsets:
, each of them being an equijoin, however,
SQL Server
's optimizer is not smart enough to see it in the query you wrote (though they are logically equivalent).我使用以下代码从条件中获得不同的结果
这对我有用。
I use following code for get different result from condition
That worked for me.
您可以使用 UNION ALL 代替
You can use UNION ALL instead