Si nos fijamos en los 2 planes de ejecución, ¿hay una respuesta fácil para cuál es mejor? A propósito NO creé índices, por lo que es más fácil ver lo que está sucediendo.
El segundo plan tiene un costo estimado más bajo, por lo que en ese sentido limitado es "mejor".
Los conjuntos de datos son tan pequeños que el optimizador no pasó mucho tiempo buscando alternativas. La primera forma de la consulta es encontrar un plan usando hash join y un spool de tabla desde el principio. El costo estimado de ese plan es tan bajo que el optimizador no se molesta en buscar algo mejor.
La segunda forma de la consulta es encontrar un plan utilizando solo uniones externas de bucles anidados al principio del proceso de búsqueda, y nuevamente el optimizador decide que el plan es lo suficientemente bueno. Sucede que se estima que este plan es más barato.
Dicho esto (como se menciona en los comentarios de la pregunta), las dos consultas no son semánticamente idénticas. Esto puede no ser importante para usted si puede garantizar que los resultados siempre serán los mismos para todos los posibles estados futuros de su base de datos, pero el optimizador no puede hacer esa suposición. Solo produce planes garantizados para producir los mismos resultados especificados por el SQL, en todas las circunstancias.
Me di cuenta de que la sintaxis anidada también modifica el comportamiento de la consulta.
La 'sintaxis anidada' es solo un aspecto de toda la especificación de sintaxis de unión ANSI. Para habilitar una especificación lógica completa para patrones de unión más complejos, la especificación permite paréntesis (opcionales) y FROM
subconsultas de cláusulas.
La consulta se puede escribir usando la misma sintaxis ANSI usando paréntesis:
SELECT
A.*,
M.*,
N.*
FROM dbo.Autos AS A
LEFT JOIN
(
dbo.Manufacturers AS N
JOIN dbo.Models AS M
ON M.ManufacturerID = N.ManufacturerID
) ON M.ModelID = A.ModelID;
Este formulario muestra claramente que el requisito lógico es dejar la unión desde Autos
el resultado de la unión interna Manufacturers
hasta Models
. Omitir los paréntesis opcionales da la forma que llama 'anidada':
SELECT
A.*,
M.*,
N.*
FROM dbo.Autos AS A
LEFT JOIN dbo.Manufacturers AS N
JOIN dbo.Models AS M
ON M.ManufacturerID = N.ManufacturerID
ON M.ModelID = A.ModelID;
Esta no es una sintaxis diferente, solo está omitiendo paréntesis opcionales y formateando un poco.
Como Martin mencionó, también es posible en este caso expresar el requisito lógico usando uniones internas seguidas de una unión externa derecha:
SELECT
A.*,
M.*,
N.*
FROM dbo.Manufacturers AS N
JOIN dbo.Models AS M
ON M.ManufacturerID = N.ManufacturerID
RIGHT JOIN dbo.Autos AS A
ON A.ModelID = M.ModelID;
Los tres formularios de consulta anteriores usan la misma sintaxis de unión ANSI. Los tres también producen el mismo plan de ejecución física con el conjunto de datos proporcionado:
Como mencioné en mi respuesta a su pregunta anterior, las consultas que expresan exactamente el mismo requisito lógico no siempre producirán el mismo plan de ejecución. La forma de consulta lógica que prefiere usar es en gran medida una cuestión de estilo. No hay correlación entre un estilo particular y planes de consulta 'mejores' en general. En general, aconsejaría no reescribir una consulta para obtener un plan particular si la nueva consulta no es realmente idéntica desde el punto de vista lógico al original.
El estándar SQL también permite FROM
subconsultas de cláusulas, por lo que otra forma de escribir la misma especificación de consulta es:
SELECT *
FROM dbo.Autos AS A
LEFT JOIN
(
SELECT
N.ManufacturerID,
ManufacturerName = N.Name,
M.ModelID,
ModelName = M.Name
FROM dbo.Manufacturers AS N
JOIN dbo.Models AS M
ON M.ManufacturerID = N.ManufacturerID
) AS R1
ON R1.ModelID = A.ModelID;
Usando la sintaxis tradicional, tenemos que cambiar la unión a `Fabricantes por una unión externa, así ... pero esto cambia el plan de consulta.
Esto probablemente cambia el significado de la consulta, en cuyo caso técnicamente no es una alternativa válida (pero vea el comentario de ypercube sobre su pregunta).
Los paréntesis (opcionales) en la sintaxis de unión ANSI están allí precisamente para requisitos de unión más complejos como este, por lo que no debe tener miedo de usarlos cuando sea necesario.