Ordem de Operações SQL – Em que Ordem o MySQL Executa Consultas?

Optimize sua base de dados, auto-magicamente.
Clique para iniciar, de graça.

Conhecer os bits e bytes da ordem de operações de uma consulta SQL pode ser muito valioso, pois pode facilitar o processo de escrita de novas consultas, ao mesmo tempo em que pode ser muito benéfico ao tentar otimizar uma consulta SQL.

Se você está procurando a versão curta, esta é a ordem lógica de operações, também conhecida como a ordem de execução, para uma consulta SQL:

  1. FROM, incluindo JOINs
  2. AQUI
  3. GRUPO POR
  4. HAVING
  5. FUNÇÕES DE JANELA
  6. SELECT
  7. DISTINTO
  8. UNION
  9. ORDENA POR
  10. LIMITE e OFFSET

Mas a realidade não é assim tão fácil nem directa. Como dissemos, o padrão SQL define a ordem de execução para as diferentes cláusulas de consulta SQL. Disse que, bancos de dados modernos já estão desafiando essa ordem padrão aplicando alguns truques de otimização que podem mudar a ordem real de execução, embora eles devem acabar retornando o mesmo resultado como se estivessem rodando a consulta na ordem de execução padrão.

Por que eles fariam isso? Bem, pode ser bobagem se o banco de dados primeiro buscaria todos os dados mencionados na cláusula FROM (incluindo os JOINs), antes de olhar para a cláusula WHERE e seus índices. Essas tabelas podem conter muitos dados, então você pode imaginar o que aconteceria se o otimizador da base de dados se mantivesse na ordem tradicional de operações de uma consulta SQL.

Vejamos cada uma das partes da consulta SQL de acordo com sua ordem de execução.

FROM e JOINs

As tabelas especificadas na cláusula FROM (incluindo os JOINs), serão avaliadas primeiro, para determinar todo o conjunto de trabalho que é relevante para a consulta. A base de dados irá fundir os dados de todas as tabelas, de acordo com as cláusulas JOINs ON, ao mesmo tempo que vai buscar os dados das subconsultas, e poderá até criar algumas tabelas temporárias para guardar os dados retornados das subconsultas nesta cláusula.

Em muitos casos, porém, o otimizador da base de dados escolherá avaliar a parte WHERE primeiro, para ver qual parte do conjunto de trabalho pode ser deixada de fora (de preferência usando índices), para não inflacionar muito o conjunto de dados se não for preciso.

Clusula WHERE

A cláusula WHERE será a segunda a ser avaliada, após a cláusula FROM. Temos o conjunto de dados em funcionamento, e agora podemos filtrar os dados de acordo com as condições da cláusula WHERE.

Estas condições podem incluir referências aos dados e tabelas da cláusula FROM, mas não podem incluir referências aos aliases definidos na cláusula SELECT, pois esses dados e esses aliases podem ainda não ‘existir’ nesse contexto, pois essa cláusula ainda não foi avaliada pela base de dados.

Also, uma armadilha comum para a cláusula WHERE seria tentar filtrar os valores agregados na cláusula WHERE, por exemplo, com esta cláusula: “WHERE sum(available_stock) > 0”. Esta declaração falhará na execução da consulta, pois as agregações serão avaliadas mais tarde no processo (veja a seção GROUP BY abaixo). Para aplicar a condição de filtragem aos dados agregados, você deve usar a cláusula HAVING e não a cláusula WHERE.

GROUP BY clause

Agora que filtramos o conjunto de dados usando a cláusula WHERE, podemos agregar os dados de acordo com uma ou mais colunas que aparecem na cláusula GROUP BY. Agrupar os dados é na verdade dividi-los em diferentes pedaços ou baldes, onde cada balde tem uma chave e uma lista de linhas que correspondem a essa chave. Não ter uma cláusula GROUP BY é como colocar todas as linhas em um enorme balde.

Após você agregar os dados, você pode agora usar funções de agregação para retornar um valor por grupo para cada um dos baldes. Tais funções de agregação incluem COUNT, MIN, MAX, SUM e outras.

HAVING clause

Agora que agrupamos os dados usando a cláusula GROUP BY, podemos usar a cláusula HAVING para filtrar alguns baldes. As condições na cláusula HAVING podem se referir às funções de agregação, então o exemplo que não funcionou na cláusula WHERE acima, funcionará muito bem na cláusula HAVING: “HAVING sum(available_stock) > 0”.

Como já agrupamos os dados, não podemos mais acessar as linhas originais neste ponto, então só podemos aplicar condições para filtrar baldes inteiros, e não linhas individuais em um balde.

Tambem, como mencionámos nas secções anteriores, os aliases definidos na cláusula SELECT também não podem ser acedidos na secção, uma vez que ainda não foram avaliados pela base de dados (isto é verdade na maioria das bases de dados).

Funções de janela

Se estiver a utilizar funções de janela, este é o ponto onde serão executados. Assim como o mecanismo de agrupamento, as funções Window também estão executando um cálculo em um conjunto de linhas. A principal diferença é que ao usar as funções Window, cada linha manterá sua própria identidade e não será agrupada em um balde de outras linhas similares.

As funções Window só podem ser usadas na cláusula SELECT ou na cláusula ORDER BY. Você pode usar funções de agregação dentro das funções Window, por exemplo:

SUM(COUNT(*)) OVER ()

cláusulaSELECT

Agora que terminamos de descartar as linhas do conjunto de dados e agrupar os dados, podemos selecionar os dados que queremos que sejam buscados da consulta para o lado do cliente. Você pode utilizar nomes de colunas, agregações e subconsultas dentro da cláusula SELECT. Tenha em mente que se você estiver utilizando uma referência a uma função de agregação, como COUNT(*) na cláusula SELECT, é apenas uma referência a uma agregação que já ocorreu quando o agrupamento ocorreu, então a agregação em si não acontece na cláusula SELECT, mas esta é apenas uma referência ao seu conjunto de resultados.

Palavra-chave DISTINCT

A sintaxe da palavra-chave DISTINCT é um pouco confusa, porque a palavra-chave toma seu lugar antes dos nomes das colunas na cláusula SELECT. Mas, a verdadeira operação DISTINCT ocorre após o SELECT. Ao utilizar a palavra-chave DISTINCT, a base de dados irá descartar linhas com valores duplicados das linhas restantes após a filtragem e agregações ter ocorrido.

Palavra-chave UNION

A palavra-chave UNION combina os conjuntos de resultados de duas consultas em um conjunto de resultados. A maioria das bases de dados permitirá que você escolha entre UNION DISTINCT (que irá descartar linhas duplicadas do conjunto de resultados combinados) ou UNION ALL (que apenas combina os conjuntos de resultados sem aplicar nenhuma verificação de duplicação).

Você pode aplicar ordenação (ORDER BY) e limitação (LIMIT) no conjunto de resultados do UNION, da mesma forma que você pode aplicá-lo em uma consulta regular.

CláusulaORDER BY

A ordenação ocorre quando a base de dados tem todo o conjunto de resultados pronto (após filtragem, agrupamento, remoção da duplicação). Assim que tivermos isso, a base de dados pode agora ordenar o conjunto de resultados usando colunas, aliases selecionados ou funções de agregação, mesmo que eles não façam parte dos dados selecionados. A única exceção é quando se usa a palavra-chave DISTINCT, o que impede a ordenação por uma coluna não selecionada, pois nesse caso a ordem do conjunto de resultados será indefinida.

Você pode escolher ordenar os dados usando uma ordem decrescente (DESC) ou uma ordem ascendente (ASC). A ordem pode ser única para cada uma das partes da ordem, portanto o seguinte é válido: ORDER BY firstname ASC, age DESC

LIMIT e OFFSET

Na maioria dos casos de uso (excluindo alguns como relatórios), gostaríamos de descartar todas as linhas, exceto as primeiras X linhas do resultado da consulta. A cláusula LIMIT, que é executada após a ordenação, nos permite fazer exatamente isso. Além disso, você pode escolher de qual linha começar a buscar os dados e quantos excluir, usando uma combinação das palavras-chave LIMIT e OFFSET. O exemplo seguinte irá buscar 50 linhas a partir da linha #100: LIMIT 50 OFFSET 100

Optimize a sua base de dados, auto-magicamente.
Clique para começar, de graça.

Deixe uma resposta

O seu endereço de email não será publicado.