MySQL: Seqüência ( precedência ) de execução de uma query SQL

Uma das grandes buscas, para quem trabalha com banco de dados, é tornar as consultas mais rápidas, principalmente em bancos de dados com um número de registro grande (algo em torno de 5 milhões registros em uma tabela).

Para começar esta análise, melhor entender como o MySQL trabalha nas consultas em tempo de execução.

Diferente do que, pelo parâmetro -h de nosso cérebro acredita, as coisas não são bem como se mostram na escrita de uma query. A seqüência de execução de um select, não é como pensamos. Esta forma de precedência das cláusulas do MySQL pode ajudar a entender e como melhor construir as consultas.

A precedência é essa:

  • Cláusula FROM
  • Cláusula WHERE
  • Cláusula GROUP BY
  • Cláusula HAVING
  • Cláusula SELECT
  • Cláusula ORDER BY

Vamos discutir:

Cláusula FROM
Como esta é a primeira cláusula a rodar, torna-se bem interessante restringir a entrada de dados e o volume a ser processado aqui.
Uma dica valiosa…
Faça relacionamentos usando, como no exemplo:

SELECT * FROM tabela1 INNER JOIN tabela2 ON (tabela1.id=tabela2.id AND tabela2.tipo=5)

Explicando… Estou pegando dados relacionados da tabela1 e da tabela2 pelo campo id das duas e impondo que só preciso dos dados da tabela que tenha tabela2.tipo=5… Com isso, os outros tipos, sejam lá quais forem, não terão a entrada nos dados válidos para a consulta. Mais ainda… Se a tabela1 e tabela2 formariam, por exemplo, 49000 registros, separados pelo tipo 5, isso ficaria em 780 registros dos 49000 registros totais, por exemplo, apenas os 780 registros serão dados como entrada pela cláusula FROM desta query. O meu espaço amostral restringiu bastante.

Cláusula WHERE
Como a cláusula WHERE é a segunda a rodar na consulta, podemos enfrentar problemas de não ter disponível algo porque a precedência não foi obedecida.

Exemplo:
SELECT marcas AS VEICULO não me permitirá utilizar na cláusula WHERE, o alias VEICULO, porque VEICULO não foi formado ainda porque o SELECT ainda não rodou…

Na WHERE, procure colocar os dados mais acertivos da análise, depois de tê-los restringidos no FROM.

Cláusula ORDER BY
Agora é a confusão geral… Os dados das colunas do SELECT não estão disponíveis na cláusula WHERE, mas eles estão disponíveis na cláusula ORDER BY!!!

Como SELECT é executada antes de ORDER BY, os dados do SELECT estarão disponíveis quando for executado o ORDER BY.

Para acompanhar a execução, use o comando EXPALIN.

É isso, espero ter esclarecido.

2 comentários em “MySQL: Seqüência ( precedência ) de execução de uma query SQL”

    • Pode parecer muito estranho, mas é… Analisando pela precedência… Com o uso do FROM, você restringe os dados que serão vasculhados…

      O problema é que cada banco trata isso de uma forma, portanto as regras são relativas ao MySQL.

      Usar WHERE tabela1=tabela2, funcionará em qualquer banco, mas JOIN, dependendo do que você fará, poderá encontrar restrições de execução.

      Exemplo: base de dados com 250.000.000 de registros. Preciso encontrar Ana Maria Silva. Se colocar a regra no FROM ele filtrará as “Ana Maria Silva”, e em vez do meu espaço amostral ser 250.000.000, passará a ser 45.000 registros para iniciar a pesquisa do WHERE com as demais condições, sacou ,né? hauhauahau

      Isso porque ele processa o FROM antes de entregar seu resultado para o WHERE.

      Tem dúvidas? Pegue uma tabela sua, não precisa ser grande, faça:

      EXPLAIN SELECT * FROM tabela1,tabela2 WHERE tabela1.id=tabela2.tabela1.id AND um_campo=um_valor

      E agora faça:

      EXPLAIN SELECT * FROM tabela1 INNER JOIN tabela2 ON (tabela1.id=tabela2.tabela1.id AND um_campo=um_valor)

      Confira os resultados de quantidades de campos analisados.

      É surpreendente…

      Abraço….

Os comentários estão encerrado.