在INNER JOIN条件下有一个“OR”是一个坏主意?
在试图提高一个非常缓慢的查询速度(在两个表上只有大约50,000行的几分钟 ,如果它很重要的话,在SQL Server 2008上),我把问题缩小到我的内部连接中的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
放入连接条件通常是一个坏主意? 或者我只是不幸地在我的桌子布局?
这种JOIN
不能优化为HASH JOIN
或MERGE JOIN
。
它可以表示为两个结果集的串联:
SELECT * FROM maintable m JOIN othertable o ON o.parentId = m.id UNION SELECT * FROM maintable m JOIN othertable o ON o.id = m.parentId
,它们中的每一个都是一个equijoin,但是, SQL Server
的优化器不够聪明,无法在你所写的查询中看到它(虽然它们在逻辑上是等价的)。