sql - unir - ¿Tener una ''O'' en una condición de UNIÓN INTERNA es una mala idea?
unir dos tablas sql server (2)
Al intentar mejorar la velocidad de una consulta inmensamente lenta (varios minutos en dos tablas con solo ~ 50,000 filas cada uno, en SQL Server 2008 si es importante), reduje el problema a un OR
en mi unión interna, como en:
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
Cambié esto a (lo que espero) un par equivalente de combinaciones a la izquierda, que se muestra aquí:
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
.. y la consulta ahora se ejecuta en aproximadamente un segundo!
¿En general es una mala idea poner un OR
en una condición de unión? ¿O simplemente tengo mala suerte de alguna manera en el diseño de mis mesas?
Este tipo de JOIN
no es optimizable para un HASH JOIN
o un MERGE JOIN
.
Se puede expresar como una concatenación de dos conjuntos de resultados:
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
Sin embargo, el optimizador de SQL Server
no es lo suficientemente inteligente como para verlo en la consulta que escribió (aunque son lógicamente equivalentes).
Utilizo el siguiente código para obtener un resultado diferente de la condición que funcionó para mí.
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)