Existe alguma diferença (desempenho, prática recomendada, etc ...) entre colocar uma condição na cláusula JOIN versus a cláusula WHERE?
Por exemplo...
-- Condition in JOIN
SELECT *
FROM dbo.Customers AS CUS
INNER JOIN dbo.Orders AS ORD
ON CUS.CustomerID = ORD.CustomerID
AND CUS.FirstName = 'John'
-- Condition in WHERE
SELECT *
FROM dbo.Customers AS CUS
INNER JOIN dbo.Orders AS ORD
ON CUS.CustomerID = ORD.CustomerID
WHERE CUS.FirstName = 'John'
Qual você prefere (e talvez por que)?
sql
performance
Steve Dignan
fonte
fonte
FROM Orders JOIN OrderParties ON Orders.Id = OrderParties.Order AND OrderParties.Type = 'Recipient' WHERE Orders.Status = 'Canceled'
Respostas:
A álgebra relacional permite a intercambiabilidade dos predicados na
WHERE
cláusula e doINNER JOIN
, portanto, mesmoINNER JOIN
consultas comWHERE
cláusulas podem ter os predicados reorganizados pelo otimizador para que eles já possam ser excluídos durante oJOIN
processo.Eu recomendo que você escreva as consultas da maneira mais legível possível.
Às vezes, isso inclui tornar o
INNER JOIN
relativamente "incompleto" e colocar alguns dos critérios noWHERE
simplesmente para facilitar a manutenção das listas de critérios de filtragem.Por exemplo, em vez de:
Escrever:
Mas isso depende, é claro.
fonte
Para junções internas, eu realmente não notei uma diferença (mas, como em todo ajuste de desempenho, você precisa verificar seu banco de dados sob suas condições).
No entanto, onde você coloca a condição, faz uma enorme diferença se você estiver usando junções esquerda ou direita. Por exemplo, considere estas duas consultas:
O primeiro fornecerá apenas os registros com um pedido datado depois de 15 de maio de 2009, convertendo assim a junção esquerda em uma junção interna. O segundo fornecerá esses registros, além de quaisquer clientes sem pedidos. O conjunto de resultados é muito diferente dependendo de onde você coloca a condição. (Selecione * se apenas para fins de exemplo, você não deve usar obviamente o código de produção.) A exceção é quando você deseja ver apenas os registros em uma tabela, mas não na outra. Então você usa a cláusula where para a condição e não a junção.
fonte
A left join B
todas as linhas de A se uniram a todas as linhas correspondentes de B. Se B não tiver nenhuma linha que corresponda, as colunas A terão um valor, mas todas as colunas de B nessa linha serão exibidas como valores NULL. Se você escreveuwhere B.somecolumn = ‘somevalue’
, você tem um NULL (B.somecolumn) sendo comparado com 'somevalue'. Qualquer coisa comparada com NULL é falsa; portanto, todas as suas linhas em que não há linha B correspondente para a linha A são eliminadas e os resultados obtidos são os mesmos que um INNER JOIN daria; portanto, a junção externa se tornou interna.funds
junção interna em (prospects.id = funds.lead_id e prospects.is_manual = 'no') e SELECT funds.id, prospects.id DAfunds
esquerda junte-se a prospects em (prospects.id = funds.lead_id) em que prospects.is_manual = 'não'A maioria dos produtos RDBMS otimiza as duas consultas de forma idêntica. No "SQL Performance Tuning" de Peter Gulutzan e Trudy Pelzer, eles testaram várias marcas de RDBMS e não encontraram diferença de desempenho.
Prefiro manter as condições de junção separadas das condições de restrição de consulta.
Se você estiver usando
OUTER JOIN
algumas vezes, é necessário colocar condições na cláusula join.fonte
ONDE será filtrado após a ocorrência de JOIN.
Filtre o JOIN para impedir a adição de linhas durante o processo JOIN.
fonte
ON
Prefiro que o JOIN junte tabelas / exibições completas e, em seguida, use o WHERE Para apresentar o predicado do conjunto resultante.
Parece sintaticamente mais limpo.
fonte
Normalmente, vejo o desempenho aumentar ao filtrar a junção. Especialmente se você puder ingressar em colunas indexadas para ambas as tabelas. Você também deve reduzir as leituras lógicas com a maioria das consultas, o que é, em um ambiente de alto volume, um indicador de desempenho muito melhor que o tempo de execução.
Sempre me divirto levemente quando alguém mostra seu benchmarking SQL e executa duas versões de um sproc 50.000 vezes à meia-noite no servidor de desenvolvimento e compara os tempos médios.
fonte
Colocar a condição na junção parece "semanticamente errada" para mim, pois não é para isso que servem os JOINs. Mas isso é muito qualitativo.
Problema adicional: se você decidir alternar de uma junção interna para, digamos, uma junção correta, ter a condição dentro de JOIN pode levar a resultados inesperados.
fonte
As junções são mais rápidas na minha opinião quando você tem uma tabela maior. Realmente não é muita diferença, especialmente se você estiver lidando com uma mesa menor. Quando soube pela primeira vez sobre junções, foi-me dito que as condições nas junções são exatamente como as condições da cláusula where e que eu poderia usá-las alternadamente se a cláusula where fosse específica sobre a tabela em que a condição seria executada.
fonte
É melhor adicionar a condição na associação. O desempenho é mais importante que a legibilidade. Para conjuntos de dados grandes, isso importa.
fonte