As seguintes consultas SQL são as mesmas:
SELECT column1, column2
FROM table1, table2
WHERE table1.id = table2.id;
SELECT column1, column2
FROM table1 JOIN table2
ON table1.id = table2.id;
E certamente resultam nos mesmos planos de consulta em todos os DBMS que eu já tentei.
Mas, de vez em quando, leio ou ouço uma opinião de que uma é definitivamente melhor que a outra. Naturalmente, essas alegações nunca são substanciadas com uma explicação.
Onde trabalho, a segunda versão parece ser favorecida pela maioria dos outros desenvolvedores e, portanto, também costumo seguir esse estilo para minimizar a surpresa. Mas, no meu coração, estou realmente pensando no primeiro (já que foi assim que o aprendi originalmente).
Uma dessas formas é objetivamente melhor que a outra? Caso contrário, quais seriam os motivos para usar um sobre o outro?
sql
coding-style
SingleNegationElimination
fonte
fonte
Respostas:
Acho que a segunda forma é melhor. Talvez seja por isso que eu aprendi, admito, mas tenho uma razão concreta: a separação de preocupações. Colocar os campos que você está usando para ingressar nas tabelas na cláusula where pode levar a dificuldades para entender as consultas.
Por exemplo, faça a seguinte consulta:
A consulta acima possui condições de junção de tabela e condições reais de lógica de negócios combinadas em um único espaço. Com uma consulta grande, isso pode ser muito difícil de entender.
No entanto, agora pegue este código:
Nesse caso, qualquer coisa relacionada às tabelas ou como elas se relacionam é toda isolada na cláusula from, enquanto a lógica de negócios real da restrição de consulta está na cláusula where. Eu acho que isso é muito mais compreensível, principalmente para consultas maiores.
fonte
A sintaxe de junção substituiu a antiga sintaxe de vírgula em 1992. Atualmente, não há motivo para escrever código com a sintaxe de vírgula. Você não ganha nada e está sujeito a alguns problemas que simplesmente não possui com sintaxe explícita.
Em primeiro lugar, à medida que você obtém consultas mais complicadas, é muito fácil fazer uma junção cruzada acidental, perdendo uma condição where. Isso é algo que a sintaxe de junção explícita pode impedir que aconteça, pois você receberá um erro de sintaxe.
Se você pretende uma junção cruzada, a sintaxe de junção explícita deixará isso claro, enquanto na sintaxe implícita alguém que faz manutenção pode assumir que você esqueceu de adicionar a cláusula where.
Depois, há o problema de junções esquerda e direita que são problemáticas em pelo menos alguns dbs usando a sintaxe implícita. Eles foram descontinuados no SQL Server e, na verdade, não retornam resultados corretos de maneira confiável, mesmo nas versões mais antigas. Nenhuma consulta que precise de uma associação externa deve conter a sintaxe implícita no SQL Server.
Além disso, vi perguntas aqui e em outros sites em que resultados errados ocorreram quando as pessoas misturam as junções implícitas e explícitas (ao adicionar uma junção esquerda, por exemplo); portanto, é uma má idéia misturá-las.
Finalmente, muitas pessoas que usam junções implícitas realmente não entendem junções. Esse é um entendimento crítico que você deve ter para consultar efetivamente um banco de dados.
fonte
Ha. Por acaso encontrei uma resposta possível para minha própria pergunta, enquanto olhava a documentação do PostgreSQL . Para resumir o que esta página explica, a consulta resultante ainda é a mesma, mas o número de planos que o otimizador deve considerar cresce exponencialmente com o número de junções.
Após cerca de seis dessas junções, o número é tão grande que o tempo para planejar a consulta pode ser perceptível e, depois das dez, o otimizador passa de uma pesquisa exaustiva de planos para uma pesquisa probabilística e pode não chegar ao plano ideal. .
Ao definir um parâmetro de tempo de execução, você pode instruir o planejador a tratar as junções internas e cruzadas mencionadas explicitamente de maneira diferente das junções implícitas, forçando-as ao topo do plano e não explorando outras opções.
De notar, o comportamento padrão é o mesmo em ambos os casos, e que obter planos alternativos requer conhecimento dos internos dos dbms e das peculiaridades das tabelas em questão para obter um resultado diferente
fonte
Bem, aqui está a visão da teoria dos conjuntos:
Quando você usa uma vírgula para separar dois (ou mais) nomes de tabela, o que você pretende é o produto cartesiano. Cada linha da tabela 'esquerda' será 'correspondida' (concatenada) com a da tabela direita.
Agora, se você escrever algo na cláusula where, é como colocar uma condição nessa 'concatenação' dizendo quais linhas 'concatenar' com quais linhas.
Na verdade, isso é "unir" as linhas :) e, portanto, a palavra-chave join que ajuda a fornecer uma sintaxe mais legível e é mais compreensível que você "de fato" queira ingressar em alguns valores comuns. Semelhante ao que @Dustin esclareceu acima.
Agora, todo DBMS é inteligente, ou seja, ele não calcula o produto cartesiano primeiro e depois filtra os dados (extremamente desperdiçador), mas o faz com base na estrutura da consulta. A única coisa em que consigo pensar é que, quando você pede para 'ingressar', é como tornar a atividade de junção explícita e provavelmente ajuda a executar o código mais rapidamente (em quanto? Você precisará criar um perfil e ver), mas no caso separado por vírgula, ele precisa de algum tempo para 'descobrir' a melhor estratégia. Posso estar errado, mas estou apenas tentando adivinhar como alguém poderia codificá-lo ...
fonte
Eu acho que geralmente é melhor usar instruções JOIN para esse caso.
Se, no futuro, surgir uma situação que exija a alteração de uma declaração de INNER JOIN para OUTTER JOIN, isso será muito mais fácil com a segunda declaração.
fonte
Qualquer RDBMS fará com que eles sejam a mesma coisa em termos de execução. Tudo se resume a se é mais legível e expressivo.
Use o JOIN para ficar claro o que é a correspondência de junção e o que é a seleção real, como em:
vs.
O último caso deixa imediatamente claro qual é a condição de junção e qual é o critério de seleção.
fonte
Eu só vi os dois resultados uma vez em um conjunto diferente de otimizações e, se a memória serve, estava no ms-sql2k em uma consulta realmente complicada. Nesse exemplo, a forma antiga usada com * = resultou em um desempenho cerca de 4x mais rápido. Ninguém, incluindo nossos técnicos da Microsoft, poderia explicar o porquê. Os caras da MS classificaram isso como um erro. Eu nunca mais vi isso.
Como a maioria dos RDBMS é inteligente o suficiente para não fazer cartesianos completos, a maior razão pela qual posso pensar em não usá-lo (além de ser depreciado) é que a maioria das pessoas com menos de 30 a 35 anos com quem trabalhei nunca viu o forma antiga antes e se perder terrivelmente quando a encontram.
fonte
O estilo antigo foi descontinuado, você não deve usá-lo.
Nem deveria haver uma discussão sobre qual é a melhor ou não. O novo código não deve usar a sintaxe antiga.
fonte
Uma razão para a sintaxe mais concisa é que ela é mais concisa, portanto, se você estiver confortável com ela, é mais fácil ler. Penso no caso detalhado como semelhante à escrita aritmética em COBOL, por exemplo, MULTIPLICAR A POR B DANDO C.
fonte