He escuchado información mixta sobre esto y espero una opinión canónica o experta.
Si tengo múltiples LEFT OUTER JOIN
s, cada uno dependiente del último, ¿es mejor anidarlos?
Para un ejemplo artificial, el JOIN
to MyParent
depende del JOIN
to MyChild
:
http://sqlfiddle.com/#!3/31022/5
SELECT
{columns}
FROM
MyGrandChild AS gc
LEFT OUTER JOIN
MyChild AS c
ON c.[Id] = gc.[ParentId]
LEFT OUTER JOIN
MyParent AS p
ON p.[id] = c.[ParentId]
En comparación con http://sqlfiddle.com/#!3/31022/7
SELECT
{columns}
FROM
MyGrandChild AS gc
LEFT OUTER JOIN
(
MyChild AS c
LEFT OUTER JOIN
MyParent AS p
ON p.[id] = c.[ParentId]
)
ON c.[Id] = gc.[ParentId]
Como se muestra arriba, estos producen diferentes planes de consulta en SS2k8
JOIN
es unINNER JOIN
ON ... ON
dos veces seguidas (paréntesis o no) es muy confuso.use plan
sugerencia funciona al trasplantar el segundo plan de consulta al primero pero no al revés.Respuestas:
Esta no es una respuesta canónica, pero noté que para los planes de consulta de bucles anidados que se muestran en el Fiddle de SQL, era posible aplicar el plan de la Consulta 2 a la Consulta 1 con el uso de la
USE PLAN
sugerencia, pero al intentar la operación inversa falla conLa desactivación de la regla de transformación del optimizador
ReorderLOJN
evita que la sugerencia de plan previamente exitosa también tenga éxito.Experimentar con mayores cantidades de datos muestra que SQL Server ciertamente también es capaz de transformarse
(A LOJ B) LOJ C
deA LOJ (B LOJ C)
forma natural, pero no vi ninguna evidencia de que lo contrario sea cierto.Un caso muy artificial en el que la primera consulta funciona mejor que la segunda es
Que da planes
Para mí, la Consulta 1 tuvo un tiempo transcurrido de 108 ms frente a 1,163 ms para la Consulta 2.
Consulta 1
Consulta 2
Por lo tanto, se puede suponer provisionalmente que la primera sintaxis ("no verificada") es potencialmente beneficiosa, ya que permite que se consideren más órdenes de unión potenciales, pero no he realizado pruebas lo suficientemente exhaustivas como para tener mucha confianza en esto como regla general.
Es muy posible que se presenten ejemplos contrarios en los que la consulta 2 funcione mejor. Pruebe ambos y mire los planes de ejecución.
fuente
no existe un tipo de JOIN llamado "Unión anidada". Es una variación más de la escritura. JOIN puede ser para fines de conveniencia de legibilidad. puede verlos como "Subconsultas" solo para comprender el propósito.
Si le preocupa más la legibilidad del código, mi opinión es que es la elección individual con qué se puede conferir.
Y si le preocupa el rendimiento de la consulta, y la sugerencia "Forzar orden de unión" no se utiliza en la consulta, no importa si la consulta se escribe con "Unión anidada" o "Unión externa". El servidor SQL presenta el orden en función del costo de unir dos tablas y / o resultados. SQL Server hace la UNIÓN entre dos conjuntos de datos a la vez solamente.
de hecho, imagine que de la segunda manera "unión anidada" si el servidor SQL decide hacer la segunda parte, "MyChild AS c IZQUIERDA EXTERIOR UNIRSE a MyParent AS p ON p. [id] = c. [ParentId]" y esas tablas suceden tener filas que se descartarán en SIGUIENTE IZQUIERDA UNIRSE. en ese caso, el servidor SQL ha gastado recursos innecesarios en hacer la UNIÓN EXTERNA a estos dos y pasar ese resultado a la siguiente UNIÓN.
También puede ver preguntas similares formuladas y respondidas adecuadamente aquí. Comprender la sintaxis de 'unión anidada'
fuente
FORCE JOIN ORDER
pista?