在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 JOINMERGE 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的优化器不够聪明,无法在你所写的查询中看到它(虽然它们在逻辑上是等价的)。