Ouvi informações confusas sobre isso e espero uma opinião canônica ou especializada.
Se eu tiver vários LEFT OUTER JOIN
s , cada um dependente do último, é melhor aninhá-los?
Para um exemplo artificial, o JOIN
to MyParent
depende do 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]
Comparado com 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 mostrado acima, eles produzem planos de consulta diferentes em SS2k8
Esta não é absolutamente uma resposta canônica, mas notei que, para os planos de consulta de loops aninhados mostrados no SQL Fiddle, era possível aplicar o plano da Consulta 2 à Consulta 1 com o uso da
USE PLAN
dica, mas a tentativa da operação reversa falha comDesativar a regra de transformação do otimizador
ReorderLOJN
impede que a dica de plano bem-sucedida anterior também seja bem-sucedida.Experimentar com maiores quantidades de dados mostra que o SQL Server certamente também é capaz de
(A LOJ B) LOJ C
se transformarA LOJ (B LOJ C)
naturalmente, mas não vi nenhuma evidência de que o inverso seja verdadeiro.Um caso muito artificial em que a primeira consulta tem um desempenho melhor que o segundo é
Que dá planos
Para mim, a Consulta 1 teve um tempo decorrido de 108 ms contra 1.163 ms para a Consulta 2.
Consulta 1
Consulta 2
Portanto, pode-se presumir provisoriamente que a primeira sintaxe ("desaninhada") é potencialmente benéfica, pois permite que mais pedidos de junção em potencial sejam considerados, mas não fiz testes exaustivos o suficiente para ter muita confiança nisso como regra geral.
Pode muito bem ser inteiramente possível criar exemplos contrários em que a Consulta 2 tenha um desempenho melhor. Experimente os dois e veja os planos de execução.
não existe tal tipo de JOIN chamado "Nested Join". é uma outra variação de escrita que o JOIN pode ser para fins de conveniência de legibilidade. você pode vê-los como "Subconsultas" apenas para fins de compreensão.
se você está mais preocupado com a legibilidade do código, então minha opinião é que é uma escolha individual com o que eles podem ser conferidos.
E se você estiver preocupado com o desempenho da consulta e a dica "Force JOIN ORDER" não for usada na consulta, não importa se a consulta for escrita com "Nested Join" ou All "Outer Join". O servidor SQL cria o pedido com base no custo de unir duas tabelas e/ou resultado. O SQL Server faz o JOIN apenas entre dois conjuntos de dados por vez.
na verdade, imagine que na segunda forma "nested join" se o SQL server decidir fazer a segunda parte, "MyChild AS c LEFT OUTER JOIN MyParent AS p ON p.[id] = c.[ParentId]" e essas tabelas acontecerem para ter linhas que serão descartadas em NEXT LEFT JOIN. nesse caso, o servidor SQL gastou recursos desnecessários fazendo o OUTER JOIN desses dois e passando esse resultado para o próximo JOIN.
você também pode ver perguntas semelhantes feitas e respondidas adequadamente aqui. Compreendendo a sintaxe de 'junção aninhada'