在尝试提高极其缓慢的查询的速度(在两个表上只有大约 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
,它们中的每一个都是等值连接,但是,SQL Server
的优化器不够聪明,无法在您编写的查询中看到它(尽管它们在逻辑上是等价的)。
我使用以下代码从对我有用的条件中获得不同的结果。
Select A.column, B.column
FROM TABLE1 A
INNER JOIN
TABLE2 B
ON A.Id = (case when (your condition) then b.Id else (something) END)
您可以改用 UNION ALL
SELECT mt.ID, mt.ParentID, ot.MasterID
FROM dbo.MainTable AS mt
UNION ALL
SELECT mt.ID, mt.ParentID, ot.MasterID
FROM dbo.OtherTable AS ot
OR
条件的 JOIN
相比,UNION ALL
将为您提供重复项。
union all
编写了它,这与您链接到的文章所描述的不正确。
不定期副业成功案例分享
ON w=x OR y=z
模式的连接?ON w=x OR y=z
形式的所有连接? (谢谢你的耐心!)SQL Server
了解需要串联。比如说,如果两个字段都被索引,那么查询SELECT * FROM othertable WHERE parentId = 1 OR id = 2
将使用连接,所以理论上没有什么可以阻止在循环中做同样的事情。SQL Server
是否会实际制定这个计划,取决于很多因素,但我从未在现实生活中看到过它。