我有一个这样的查询:
SELECT ordIdent.Identifier, ord.OrderId
FROM OrderIdentifier ordIdent
JOIN [order] ord
ON ordIdent.OrderId = ord.OrderId
WHERE ordIdent.Identifier = '29584'
OR ord.ClientOrderId = '29584'
这个想法是我们正在使用值'29584'进行搜索,但我们真的不知道它是 aClientOrderId
还是 an Identifier
,所以我们想同时搜索两者。
这给出了非常糟糕的性能。它提取了数百万行(12.5 万行来自另一个,2000 万行来自另一个)
但是这个查询:
SELECT ordIdent.Identifier, ord.OrderId
FROM OrderIdentifier ordIdent
JOIN [order] ord
ON ordIdent.OrderId = ord.OrderId
WHERE ord.ClientOrderId = '01193504'
UNION
SELECT ordIdent.Identifier, ord.OrderId
FROM OrderIdentifier ordIdent
JOIN [order] ord
ON ordIdent.OrderId = ord.OrderId
WHERE ordIdent.Identifier = '01193504'
有很好的表现。通常我会这样做并收工。
但是我的实际查询非常大,我宁愿不调用它两次(尽管它仍然比使用“或”更好。)所以在我将它设置为被调用两次之前,我想我会四处询问看看如果我有其他选择。
看来我应该做某种左连接来完成这项工作。但我似乎无法绕过它。
有没有办法在一个有左连接而不是“OR”的查询中做到这一点? (或者其他类型的选择?)
更新:
好的,我开始考虑它,我意识到我可以将 OR 分解为使用union
的 CTE,然后将 CTE 用于实际查询。
如果有更好的方法来处理它,我将保持打开状态,但 CTE 解决了我的问题。
我认为您可以重写该查询以使用
FULL OUTER JOIN
:但你为什么想要?您最终将使用该语法从两个表中读取所有行,这会导致您试图避免的性能问题。
UNION
或者UNION ALL
是去这里的正确方式。对于像你这样的过滤器,你仍然可以UNION ALL
像这样使用:有时这样做会带来轻微的性能优势。这取决于您的数据。