Em todas as empresas em que trabalhei, descobri que as pessoas ainda estão escrevendo suas consultas SQL no padrão ANSI-89:
select a.id, b.id, b.address_1
from person a, address b
where a.id = b.id
em vez do padrão ANSI-92:
select a.id, b.id, b.address_1
from person a
inner join address b
on a.id = b.id
Para uma consulta extremamente simples como esta, não há uma grande diferença na legibilidade, mas para consultas grandes, acho que ter meus critérios de junção agrupados com a listagem da tabela torna muito mais fácil ver onde posso ter problemas em minha junção, e deixe-me manter toda a minha filtragem na minha cláusula WHERE. Sem mencionar que acho que as junções externas são muito mais intuitivas do que a sintaxe (+) do Oracle.
Enquanto tento divulgar o ANSI-92 para as pessoas, há algum benefício concreto de desempenho no uso do ANSI-92 em vez do ANSI-89? Eu tentaria sozinho, mas as configurações do Oracle que temos aqui não nos permitem usar o EXPLAIN PLAN - não gostaria que as pessoas tentassem otimizar seu código, não é?
Respostas:
De acordo com o "SQL Performance Tuning" de Peter Gulutzan e Trudy Pelzer, das seis ou oito marcas de RDBMS testadas, não houve diferença na otimização ou desempenho do SQL-89 em relação às junções do estilo SQL-92. Pode-se supor que a maioria dos motores RDBMS transformam a sintaxe em uma representação interna antes de otimizar ou executar a consulta, portanto, a sintaxe legível por humanos não faz diferença.
Eu também tento evangelizar a sintaxe SQL-92. Dezesseis anos depois de ser aprovado, é hora de as pessoas começarem a usá-lo! E todas as marcas de banco de dados SQL agora o suportam, então não há razão para continuar a usar a
(+)
sintaxe Oracle não padrão ou sintaxe*=
Microsoft / Sybase.Quanto ao porquê de ser tão difícil quebrar a comunidade de desenvolvedores do hábito do SQL-89, só posso supor que existe uma grande "base da pirâmide" de programadores que codificam copiando e colando, usando exemplos antigos de livros, artigos de revistas, ou outra base de código, e essas pessoas não aprendem nova sintaxe de forma abstrata. Algumas pessoas combinam com o padrão e outras aprendem mecanicamente.
No entanto, estou gradualmente vendo pessoas usando a sintaxe SQL-92 com mais frequência do que antes. Tenho respondido a perguntas sobre SQL online desde 1994.
fonte
Bem, o padrão ANSI092 inclui uma sintaxe bastante hedionda. As junções naturais são uma e a cláusula USING é outra. IMHO, a adição de uma coluna a uma tabela não deve quebrar o código, mas um NATURAL JOIN quebra de uma forma flagrante. A "melhor" maneira de quebrar é por erro de compilação. Por exemplo, se você selecionar * em algum lugar, a adição de uma coluna podefalhar ao compilar. A próxima melhor maneira de falhar seria um erro de tempo de execução. É pior porque seus usuários podem ver, mas ainda assim fornece um bom aviso de que você quebrou algo. Se você usar ANSI92 e escrever consultas com junções NATURAL, ele não será interrompido em tempo de compilação e não será interrompido em tempo de execução, a consulta de repente começará a produzir resultados errados. Esses tipos de bugs são insidiosos. Os relatórios dão errado, a divulgação potencialmente financeira está incorreta.
Para quem não está familiarizado com NATURAL Joins. Eles unem duas tabelas em cada nome de coluna que existe em ambas as tabelas. O que é muito legal quando você tem uma chave de 4 colunas e está cansado de digitá-la. O problema surge quando a Tabela1 tem uma coluna pré-existente chamada DESCRIPTION e você adiciona uma nova coluna à Tabela2 chamada, ah, não sei, algo inócuo como, mmm, DESCRIPTION e agora você está juntando as duas tabelas em um VARCHAR2 (1000) campo de formato livre.
A cláusula USING pode levar à ambigüidade total, além do problema descrito acima. Em outra postagem do SO , alguém mostrou este ANSI-92 SQL e pediu ajuda para lê-lo.
Isso é completamente ambíguo. Eu coloquei uma coluna UserID nas tabelas Empresas e usuários e não há reclamação. E se a coluna UserID nas empresas for o ID da última pessoa a modificar essa linha?
Estou falando sério, alguém pode explicar por que essa ambigüidade foi necessária? Por que ele está embutido no padrão?
Acho que Bill está correto ao dizer que existe uma grande base de desenvolvedores que copiam / colam lá por meio da codificação. Na verdade, posso admitir que sou meio que um quando se trata de ANSI-92. Todos os exemplos que já vi mostravam várias junções aninhadas entre parênteses. Honestamente, isso torna a escolha das tabelas no sql difícil na melhor das hipóteses. Mas então um evangilista SQL92 explicou que isso realmente forçaria uma ordem de junção. JESUS ... todos aqueles Copy pasters que vi agora estão realmente forçando uma ordem de junção - um trabalho que 95% do tempo é melhor deixar para otimizadores, especialmente um copy / paster.
Tomalak acertou quando disse:
Tem que me dar algo e não vejo um lado bom. E se houver um lado positivo, os negativos são um albatroz grande demais para serem ignorados.
fonte
SELECT *
(descobrir que o cliente depende da ordem do campo) - Parece um pouco desleixadoAlgumas razões vêm à mente:
De minha parte, faço todas as minhas junções na sintaxe SQL-92 e converto o código onde posso. É a maneira mais limpa, legível e poderosa de fazer isso. Mas é difícil convencer alguém a usar o novo estilo, quando eles pensam que isso os prejudica em termos de mais trabalho de digitação sem alterar o resultado da consulta.
fonte
Em resposta à postagem NATURAL JOIN e USING acima.
POR QUE você veria a necessidade de usar isso - eles não estavam disponíveis em ANSI-89 e foram adicionados para ANSI-92 como o que eu posso ver apenas como um atalho.
Eu nunca deixaria uma junção ao acaso e sempre especificaria a tabela / alias e id.
Para mim, a única maneira de ir é ANSI-92. É mais detalhado e a sintaxe não é apreciada pelos seguidores ANSI-89, mas separa nitidamente suas JOINS de sua FILTRAGEM.
fonte
Primeiro, deixe-me dizer que no SQL Server a sintaxe de junção externa (* =) não fornece resultados corretos o tempo todo. Há momentos em que ele interpreta isso como uma junção cruzada e não uma junção externa. Portanto, há um bom motivo para parar de usá-lo. E essa sintaxe de junção externa é um recurso obsoleto e não estará na próxima versão do SQL Server após o SQL Server 2008. Você ainda poderá fazer junções internas, mas por que alguém iria querer? Eles não são claros e são muito mais difíceis de manter. Você não sabe facilmente o que faz parte da junção e o que é realmente apenas a cláusula where.
Um motivo pelo qual acredito que você não deve usar a sintaxe antiga é que entender as junções e o que elas fazem e o que não fazem é uma etapa crítica para qualquer pessoa que queira escrever código SQL. Você não deve escrever nenhum código SQL sem compreender completamente as junções. Se você os compreender bem, provavelmente chegará à conclusão de que a sintaxe ANSI-92 é mais clara e fácil de manter. Nunca conheci um especialista em SQL que não usasse a sintaxe ANSI-92 em vez da sintaxe antiga.
A maioria das pessoas que conheci ou com quem lidei que usam o código antigo realmente não entende as junções e, portanto, tem problemas ao consultar o banco de dados. Esta é minha experiência pessoal, então não estou dizendo que seja sempre verdade. Mas, como especialista em dados, tive que consertar muito desse lixo ao longo dos anos para não acreditar.
fonte
Aprendi ANSI-89 na escola e trabalhei na indústria por alguns anos. Então eu deixei o fabuloso mundo do DBMS por 8 anos. Mas então eu voltei e esse novo material ANSI 92 estava sendo ensinado. Aprendi a sintaxe Join On e agora ensino SQL e recomendo a nova sintaxe JOIN ON.
Mas a desvantagem que vejo é que as subconsultas correlacionadas não parecem fazer sentido à luz das junções ANSI 92. Quando as informações de junção foram incluídas em WHERE e as subconsultas correlacionadas foram "juntadas" em WHERE, tudo parecia correto e consistente. No ANSI 92, os critérios de junção de tabela não estão em WHERE e a "junção" da subconsulta está, a sintaxe parece inconsistente. Por outro lado, tentar "consertar" essa inconsistência provavelmente só pioraria a situação.
fonte
Não sei a resposta com certeza .. esta é uma guerra religiosa (embora em menor grau do que Mac-Pc ou outros)
Um palpite é que, até bem recentemente, a Oracle (e talvez outros fornecedores também) não adotava o padrão ANSI-92 (acho que era no Oracle v9, ou por aí) e, portanto, para DBAs / Desenvolvedores Db trabalhando em empresas que ainda estavam usando essas versões (ou queriam que o código fosse portátil entre servidores que poderiam usar essas versões, eles tinham que seguir o padrão antigo ...
É realmente uma pena, porque a nova sintaxe de junção é muito mais legível, e a sintaxe antiga gera resultados errados (incorretos) em vários cenários bem documentados.
fonte
INNER JOIN
em 1995, emboraLEFT JOIN
não até 1996. O MySQL o tem suportado pelo menos desde 3.23, lançado em 1999; PostgreSQL pelo menos desde 7.2, lançado em 2002. Algumas buscas casuais no Google não me dão resposta para Teradata.Inércia e praticidade.
ANSI-92 SQL é como digitar por toque. De alguma forma teórica, pode melhorar tudo algum dia, mas agora posso digitar muito mais rápido olhando para as teclas com quatro dedos. Eu precisaria voltar para ir em frente, sem nenhuma garantia de que algum dia haveria um retorno.
Escrever SQL é cerca de 10% do meu trabalho. Se eu precisar do ANSI-92 SQL para resolver um problema que o ANSI-89 SQL não consegue resolver, irei usá-lo. (Eu uso no Access, na verdade.) Se usar o tempo todo me ajudasse a resolver meus problemas existentes com muito mais rapidez, eu gastaria o tempo para assimilá-lo. Mas posso sacar ANSI-89 SQL sem nunca pensar na sintaxe. Eu sou pago para resolver problemas - pensar na sintaxe SQL é uma perda de tempo e do dinheiro do meu empregador.
Algum dia, jovem Grasshopper, você estará defendendo o uso da sintaxe SQL ANSI-92 contra jovens reclamando que você deveria usar SQL3 (ou qualquer outra coisa). E então você entenderá. :-)
fonte
Tive uma consulta escrita originalmente para SQL Server 6.5, que não dava suporte à sintaxe de junção do SQL 92, ou seja,
ao invés foi escrito como
A consulta já existia há algum tempo e os dados relevantes se acumulavam para torná-la muito lenta, cerca de 90 segundos para ser concluída. Quando esse problema surgiu, tínhamos atualizado para o SQL Server 7.
Depois de mexer nos índices e outras provocações de Páscoa, alterei a sintaxe de junção para ser compatível com SQL 92. O tempo de consulta caiu para 3 segundos.
Há um bom motivo para mudar.
Repostado a partir daqui .
fonte
Posso responder do ponto de vista de um desenvolvedor médio, sabendo apenas o SQL o suficiente para entender as duas sintaxes, mas ainda pesquisando a sintaxe exata de insert cada vez que preciso ... :-P (Eu não faço SQL o dia todo , apenas corrigindo alguns problemas de vez em quando.)
Bem, na verdade, acho a primeira forma mais intuitiva, não tornando nenhuma hierarquia aparente entre as duas tabelas. O fato de eu ter aprendido SQL com livros possivelmente antigos, mostrando a primeira forma, provavelmente não ajuda ... ;-)
E a primeira referência que encontro em uma pesquisa sql select no Google (que retorna principalmente respostas em francês para mim ... ) primeiro mostra a forma mais antiga (depois explique a segunda).
Apenas dando algumas dicas sobre a pergunta "por que" ... ^ _ ^ Eu deveria ler um bom livro moderno (agnóstico do DB) sobre o assunto. Se alguém tem sugestões ...
fonte
Não posso falar por todas as escolas, mas na minha universidade, quando estávamos fazendo o módulo SQL do nosso curso, eles não ensinavam ANSI-92, eles ensinavam ANSI-89 - em um sistema VAX antigo! Não fui exposto ao ANSI-92 até que comecei a vasculhar o Access, tendo construído algumas consultas usando o designer de consulta e, em seguida, vasculhando o código SQL. Percebendo que não tinha ideia de como as junções eram concluídas, ou das implicações da sintaxe, comecei a me aprofundar para entender.
Dado que a documentação disponível não é exatamente intuitiva em muitos casos, e que as pessoas tendem a se apegar ao que sabem e, em muitos casos, não se esforçam para aprender mais do que o necessário para realizar seu trabalho, é fácil ver por que a adoção está demorando tanto.
Claro, existem aqueles evangelistas técnicos que gostam de mexer e entender e tendem a ser aqueles tipos que adotam os princípios "mais novos" e tentam converter o resto.
Estranhamente, parece-me que muitos programadores saem da escola e param de avançar; pensando que porque é isso que eles foram ensinados, é assim que se faz. Só quando você tira os antolhos é que você percebe que a escola foi criada apenas para lhe ensinar o básico e lhe dar compreensão suficiente para aprender o resto sozinho e que na verdade você mal arranhou a superfície do que há para saber; agora é seu trabalho continuar nesse caminho.
Claro, essa é apenas minha opinião com base na minha experiência.
fonte
1) Forma padrão de escrever OUTER JOIN, versus * = ou (+) =
2) JUNÇÃO NATURAL
3) Depende do mecanismo de banco de dados, as tendências ANSI-92 para serem mais otimizadas.
4) Otimização manual:
Digamos que temos a próxima sintaxe (ANSI-89):
Pode ser escrito como:
Mas também como:
Todos eles (1), (2), (3) retornam o mesmo resultado, porém são otimizados de forma diferente, depende do mecanismo de banco de dados, mas a maioria deles:
5) Consultas mais longas são menos complicadas.
fonte
Razões pelas quais as pessoas usam ANSI-89 de minha experiência prática com velhos e jovens programadores e estagiários e recém-formados:
Eu pessoalmente prefiro ANSI-92 e altero todas as consultas que vejo na sintaxe ANSI-89 às vezes apenas para entender melhor a instrução SQL em questão. Mas percebi que a maioria das pessoas com quem trabalho não tem habilidade suficiente para escrever junções em muitas tabelas. Eles codificam o melhor que podem e usam o que memorizaram na primeira vez que encontraram uma instrução SQL.
fonte
Aqui estão alguns pontos comparando SQL-89 e SQL-92 e esclarecendo alguns equívocos em outras respostas.
NATURAL JOINS
são uma ideia horrível. Eles estão implícitos e requerem meta-informações sobre a tabela. Nada sobre o SQL-92 requer seu uso, então simplesmente ignore-os . Eles não são relevantes para esta discussão.USING
é uma ótima ideia, tem dois efeitos:id
em ambas as tabelas. Depois de unir as tabelas, isso se torna ambíguo e requer aliasing explícito. Além disso, osid
s na junção quase certamente tinham dados diferentes. Se você associar pessoa a empresa, terá que criar o alias de umid
paraperson_id
e umid
paracompany_id
, sem os quais a união produziria duas colunas ambíguas. Usar um identificador globalmente exclusivo para a chave substituta da mesa é a convenção com a qual as recompensas padrãoUSING
.CROSS JOIN
. ACROSS JOIN
não reduz o conjunto, ele implicitamente o faz crescer.FROM T1,T2
é o mesmo queFROM T1 CROSS JOIN T2
, que produz uma junção cartesiana que geralmente não é o que você deseja. Ter a seletividade para reduzir isso a umaWHERE
condicional distante significa que você tem mais chances de cometer erros durante o projeto.,
explícitos do SQL-89 e do SQL-92JOIN
têm precedências diferentes.JOIN
tem uma precedência mais alta. Pior ainda, alguns bancos de dados como o MySQL erraram muito por muito tempo. . Portanto, misturar os dois estilos é uma má ideia, e o estilo muito mais popular hoje é o estilo SQL-92.fonte
A Oracle não implementa bem o ANSI-92. Tive vários problemas, principalmente porque as tabelas de dados no Oracle Apps são muito bem dotadas de colunas. Se o número de colunas em suas junções exceder cerca de 1050 colunas (o que é muito fácil de fazer no Google Apps), você receberá este erro espúrio que não faz absolutamente nenhum sentido lógico:
Reescrever a consulta para usar a sintaxe de junção de estilo antigo faz com que o problema desapareça, o que parece apontar a culpa diretamente para a implementação de junções ANSI-92.
Até encontrar esse problema, eu era um defensor constante do ASNI-92, devido aos benefícios de reduzir a chance de uma junção cruzada acidental, o que é muito fácil de fazer com a sintaxe do estilo antigo.
Agora, porém, acho muito mais difícil insistir nisso. Eles apontam para a má implementação da Oracle e dizem "Faremos do nosso jeito, obrigado."
fonte
Um novo padrão SQL herda tudo do padrão anterior, também conhecido como 'os grilhões da compatibilidade'. Portanto, o estilo de junção 'antigo' / 'separado por vírgula' / 'não qualificado' é o sytax SQL-92 perfeitamente válido.
Agora, eu argumento que o SQL-92
NATURAL JOIN
é a única junção de que você precisa. Por exemplo, eu argumento que é superiorinner join
porque não gera colunas duplicadas - não há mais variáveis de intervalo nasSELECT
cláusulas para eliminar a ambigüidade de colunas! Mas não posso esperar mudar todos os corações e mentes, então preciso trabalhar com programadores que continuarão a adotar o que eu pessoalmente considero estilos de junção legados (e eles podem até se referir a variáveis de intervalo como 'aliases'!). Essa é a natureza do trabalho em equipe e não operar no vácuo.Uma das críticas à linguagem SQL é que o mesmo resultado pode ser obtido usando uma série de sintaxes semanticamente equivalentes (algumas usando álgebra relacional, outras usando cálculo relacional), onde escolher o 'melhor' simplesmente se resume ao estilo pessoal . Portanto, estou tão confortável com as junções do 'estilo antigo' quanto com
INNER
. Se eu reservaria um tempo para reescrevê-los,NATURAL
depende do contexto.fonte