Páginas

8 de mai. de 2012

SQL padrão ANSI X padrão Oracle: Qual é mais rápido?

ATUALIZADO EM 12/03/2015


Olá pessoal,

     No artigo de hoje explicarei em detalhes a resposta de uma pergunta que é realizada por alunos em quase toda turma presencial de SQL ou SQL Tuning que eu leciono: Existe diferença de desempenho entre instruções SQL escritas no padrão ANSI ou no padrão Oracle? Antes de dar a resposta, vamos entender primeiro o que é SQL e o que são os padrões ANSI SQL e Oracle

     Resumindo, a Structured Query Language, mais conhecida pela sigla SQL, é uma linguagem que foi desenvolvida no início dos anos 70, pela IBM, para manipular bancos de dados relacionais. A partir de então, diversos fabricantes de Sistemas Gerenciadores de Bancos de Dados Relacionais (SGBDRs), como por exemplo a Oracle, começaram a desenvolver versões próprias da linguagem SQL (chamadas de dialetos ou extensões) e isso levou à necessidade da criação de uma linguagem SQL padronizada.

     Com a sua popularização e sucesso, organizações como o Instituto Americano Nacional de Padrões (ANSI) e a Organização Internacional de Padronização (ISO), resolveram padronizar a linguagem SQL. Em 1986 foi criado um padrão ANSI e em 1987 foi criado um padrão ISO. A partir de então, surgiram várias versões do padrão SQL, onde cada versão acrescenta novos comandos ou funcionalidades. Seguem abaixo alguns detalhes sobre algumas versões do padrão ANSI:
   
          - SQL-86
               - Primeira versão da linguagem, lançada em 1986, consiste basicamente na versão inicial da linguagem criada pela IBM.
   
          - SQL-92
              - Lançada em 1992, inclui novos recursos tais como tabelas temporárias, novas funções, expressões nomeadas, valores únicos, instrução CASE etc.

          - SQL:1999 (SQL3)
               - Lançada em 1999, foi a versão que teve mais recursos novos significativos, entre eles: a implementação de expressões regulares, recursos de orientação a objetos, queries recursivas, triggers, novos tipos de dados (boolean, LOB, array e outros), novos predicados etc.
  
          - SQL:2003
               - Lançada em 2003, inclui suporte básico ao padrão XML, sequências padronizadas, instrução MERGE, colunas com valores auto-incrementais etc.

          - SQL:2006:
               - Lançada em 2006, não inclui mudanças significativas para as funções e comandos SQL. Contempla basicamente a interação entre SQL e XML

 
     Atualmente, os principais fabricantes de SGBDRs, implementam em seus Bancos de Dados, além das instruções SQL referentes ao seu "dialeto", as instruções SQL do padrão ANSI mais recente. No caso de instruções SQL no SGBD Oracle, o que o pessoal costuma chamar de padrão Oracle, é o dialeto SQL da Oracle. As instruções dos dialetos normalmente surgem quando o fabricante necessita implementar recursos no SGBD, que ainda não possuem instruções correspondentes no padrão ANSI . 

     Um exemplo muito utilizado de comando SQL do dialeto Oracle, é a ligação OUTER JOIN, que o pessoal costuma escrever utilizando o caractere +. Vejam a diferença nos exemplos abaixo e na imagem 01:
   
          Instrução SQL com ligação representando LEFT JOIN utilizando o dialeto Oracle:

          SELECT      e.first_name || e.last_name NAME, 
                              D.DEPARTMENT_NAME 
          FROM         HR.EMPLOYEES E,
                              HR.DEPARTMENTS D
          WHERE      E.DEPARTMENT_ID = D.DEPARTMENT_ID (+);

   
          Instrução SQL com ligação representando LEFT JOIN utilizando o padrão ANSI:

          SELECT        E.FIRST_NAME || E.LAST_NAME NAME, 
                                D.DEPARTMENT_NAME 
          FROM          HR.EMPLOYEES E
          LEFT JOIN  HR.DEPARTMENTS D
                   ON      E.DEPARTMENT_ID = D.DEPARTMENT_ID;




Imagem 01 - Instrução SQL no padrão Oracle e padrão ANSI
  

     Agora que já sabemos o que é o padrão Oracle e o que é o padrão ANSI, vou comentar sobre alguns itens que me fazem defender o uso do padrão ANSI, antes de falar especificamente sobre a performance dos 2 padrões:

             1- Permite que você migre a aplicação contendo as instruções SQL para outro BD sem ter que fazer qualquer alteração;

             2- As ligações entre colunas são mais fáceis de serem identificadas, pois ficam fora da cláusula WHERE, separadas das condições de filtro. Essa característica pode muitas vezes facilitar manutenções futuras e evitar queries ruins. Já vi muita gente escrever queries no padrão Oracle e esquecer de incluir na cláusula WHERE a(s) coluna(s) necessária(s) para efetuar a ligação correta entre 2 tabelas. Neste caso, para evitar linhas duplicadas resultantes do produto cartesiano gerado pela falta da(s) coluna(s) necessária(s) na ligação, o desenvolvedor inclui a cláusula DISTINCT, "uma grande gambiarra para corrigir um erro de programação, que gera degradação da performance da query". Ligações no padrão ANSI forçam a inclusão de uma cláusula ON que obrigam a inclusão de uma ligação entre as tabelas;
   
     Bom... agora quanto à performance, de um modo geral, não há diferença entre o plano de execução gerado nos 2 padrões, até porque, internamente, muitas instruções escritas no padrão ANSI são convertidas para o dialeto Oracle, porém o padrão ANSI tem uma vantagem bastante conhecida, como por exemplo, permitir fazer um FULL OUTER JOIN com melhor performance e com menor complexidade do que a alternativa correspondente no dialeto Oracle. Nas Imagens 02 e 03 vemos uma instrução SQL equivalente e seu respectivo plano de execução nos padrões Oracle e ANSI. Nelas podemos observar (destacado em vermelho) que o custo da instrução SQL no padrão ANSI (7) é bem menor que o do dialeto Oracle (15) e isso implica em melhor desempenho na primeira.

Imagem 02 - Full Outer Join no dialeto Oracle

Imagem 03 - Full Outer Join no padrão ANSI

      O padrão ANSI é ensinado atualmente nos treinamentos oficiais de instruções SQL da Oracle e nos meus treinamentos Aprendendo SQL! Por todos os motivos que citei neste artigo, sugiro fortemente a utilização do padrão ANSI!
  
        
Bom pessoal, por hoje é só! Espero que tenham gostado!

[]s


Referências:
  - SQL: http://pt.wikipedia.org/wiki/SQL
  - ANSI SQL: http://allthingsoracle.com/ansi-sql/   
  - Padrão SQL e sua Evolução: http://www.ic.unicamp.br/~geovane/mo410-091/Ch05-PadraoSQL-art.pdf
  - História do Padrão SQL: http://www.altabooks.com.br/capitulos_amostra/sql_cap_amostra.pdf
  - Oracle Database SQL Reference: http://docs.oracle.com/cd/B12037_01/server.101/b10759/queries006.htm

  - Oracle Database SQL Language Reference 11GR2:  
   http://docs.oracle.com/cd/E11882_01/server.112/e10592/queries006.htm#i2054062
  - Execution Plans: Part 1 Finding plans     
http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_10002.htm#SQLRF01702 

16 comentários:

  1. Fábio, seu blog está ótimo! Muito útil!

    ResponderExcluir
  2. E ai Fabio.

    Sinceramente por uma melhor visualização e pós manutenção no código, prefiro o padrão ANSI.

    Abraços.

    Diego Melo

    ResponderExcluir
  3. Obrigado Otávio e Fernanda pelos comentários.

    Diego, também prefiro 1000 X o padrão ANSI. Sou até sistemático neste ponto. Toda vez que pego uma query fora do padrão ANSI eu reescrevo ela primeiro para o padrão ANSI para depois fazer as alterações necessárias!

    []s

    ResponderExcluir
  4. Fabio, consegues indicar-me aonde a Oracle aconselha o uso de ANSI SQL quando é usado o CBO?

    ResponderExcluir
    Respostas
    1. Anônimo, já li isso em vários sites, fóruns e blogs, onde pelo 1 deles foi algum documento da Oracle, mas não consegui achar de novo. Procurei agora na documentação online da Oracle e ainda não encontrei nada, mas quando eu achar colocarei o link ou referência aqui.

      No site do Tom Kyte (Ask Tom) existem vários itens onde ele recomenda o uso do padrão ANSI. Vou copiar abaixo o link de um desses itens que eu havia salvado, com alguns comentários dele. O Tom Kyte trabalha p/ a Oracle, portanto tbém dá p/ deduzir q é aconselhado pela Oracle o uso do padrão ANSI, oK?

      Consulte:
      http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:2419891400346921578

      there are things you can do with the ansi join syntax that would be awkward to do, or would require multiple inline views/with factored subqueries to accomplish.

      So deprecate the old syntax and concentrate in support the ANSI syntax. You
      don't have enough time, support ANSI and leave old syntax back.

      Resumindo, neste item ele fala que existem coisas que são possíveis sem padrão ANSI somente com múltiplas views inline, o que normalmente adiciona complexidade na query e gera um plano de execução com custo maior. O padrão ANSI ficou forte no Oracle com a entrada do CBO, pois a Oracle está totalmente aderente ao padrão ANSI e implementando novos recursos somente neste padrão!

      OK? Qual o seu nome?


      Excluir
    2. OK, só perguntei porque eu também me lembra de ter lido uma coisa do género do site da Oracle e não encontro.
      Eu gosto mais de ANSI SQL mas tenho tido dificuldade em conseguir que os colegas comecem a utilizar nas queries maiores.
      O meu nome é Eduardo Reis.

      Excluir
    3. Ok Eduardo, vc fez uma ótima pergunta! Infelizmente eu tbém li essa informação em algum material da Oracle que não estou encontrando de novo. Pelo menos achei no site AskTom!

      Fazer os outros usarem o padrão ANSI não é uma tarefa fácil. No meu trabalho, por exemplo, somente eu escrevo no padrão ANSI!

      []s

      Excluir
  5. Aprendi algo hoje!
    Faltou o like do facebook.

    ResponderExcluir
    Respostas
    1. Infelizmente os blogs criados no "Blogger" ainda não tem opção de incluir o LIKE do Facebook.

      Excluir
  6. Bah isso era uma disputa entre eu e meu namorado, pois ele trabalha com padrão ANSI e eu com padrão Oracle. Prefiro o Oracle por ser mais simples, mas ele estava certo na questão de preferir ANSI pela performance.
    Valeu o artigo!

    ResponderExcluir
  7. Fabio, gostei muito do seu post e o li por recomendação do seu curso Aprendendo SQL, essa informação agregou muito pra mim. Como estou aprendendo SQL todas as informações são bem vindas.

    ResponderExcluir
  8. Fábio, também li agora por indicação do Curso Aprendendo SQL, o que enriquece ainda mais o conhecimento.
    Confesso que me deparo com o desafio de atuar com o padrão SQL ANSI com certa resistência, mas é um passo importante para depois eu conseguir mergulhar num SQL SERVER ou POSTGRESQL sem medo.
    FIco bastante agradecio pela excelente abordagem e indicação.
    Parabéns!!

    ResponderExcluir
    Respostas
    1. Devidi, fico contente que você tenha gostado do artigo.
      Vai com fé que logo você se acostuma com o padrão ANSI (já passei por isso).
      []s

      Excluir