Identificar os componentes de processamento de consulta

Concluído

Há quatro estágios separados para executar a consulta. Na ordem de execução, esses estágios são:

  1. Análise
  2. Transformação (Reescritor)
  3. Planejamento
  4. Execução

O analisador

O analisador é responsável por verificar a cadeia de caracteres de consulta em busca de uma sintaxe válida. O analisador tem duas partes principais:

  • gram.y, que é composto por um conjunto de regras gramaticais e ações correspondentes.
  • scan.1 o lexer, que reconhece identificadores e palavras-chave do SQL. Cada palavra-chave ou identificador dispara um token que está sendo criado e entregue ao analisador.

O analisador cria uma árvore de consulta, que separa a consulta em partes identificáveis para entender quais tabelas estão envolvidas, quais filtros foram aplicados etc. As partes de uma árvore de consulta são:

  • Tipo de comando – SELECT, INSERT, UPDATE ou DELETE.
  • RTE (entrada de tabela de intervalo) – uma lista de relações, tabelas ie, subconsultas, resultados de junções etc. Em uma instrução SELECT, esses itens aparecem após a palavra-chave FROM.
  • Relação de resultado – a relação de resultado para comandos INSERT, UPDATE e DELETE é a tabela ou exibição em que as alterações devem entrar em vigor.
  • Lista de destino – os resultados da consulta, identificados entre as palavras-chave SELECT e FROM. Os comandos DELETE não produzem um resultado, portanto, o planejador adiciona uma entrada especial para permitir que o executor localize a linha a ser excluída. Os comandos INSERT identificam as novas linhas que devem entrar na relação de resultado. Para comandos UPDATE, a lista de destino descreve as novas linhas que devem substituir as antigas.
  • Qualificação – um valor booliano que especifica se a operação para a linha de resultado final deve ou não ser executada. Corresponde à cláusula WHERE de uma instrução SQL.
  • Árvore de junção – essa árvore pode ser uma lista dos itens FROM. As junções podem ser feitas em qualquer ordem ou feitas em uma ordem específica, como junções externas.
  • Outros – itens que não são relevantes nesta fase, como a cláusula ORDER BY.

Reescritor

A saída do analisador é passada para o processo de transformação ou reescritor, a menos que um erro seja encontrado; se isso ocorrer, uma mensagem de erro será retornada.

O reescritor de consulta reescreve o texto da consulta aplicando regras a ele. O reescritor leva em consideração as regras e passa a consulta modificada para o planejador de consultas. A segurança em nível de linha é implementada nesta fase.

Por exemplo, as regras em SELECT são sempre aplicadas como a última etapa, inclusive para consultas INSERT, UPDATE e DELETE. As regras também significam que as consultas UPDATE não substituem as linhas existentes, em vez disso, uma nova linha é inserida e a linha antiga é ocultada. Após a confirmação da transação, o processo de vácuo pode remover a linha oculta.

Planner

O trabalho do planejador é pegar as regras de consulta e entender qual entre as diferentes maneiras em que a consulta pode ser executada é a mais rápida.

O planejador cria uma árvore de plano, com nós que representam operações físicas nos dados.

O PostgreSQL usa um otimizador de consulta baseado em custo para encontrar o plano ideal para uma consulta. O planejador avalia vários planos de execução e estima quanto dos recursos necessários são necessários, como ciclos de CPU, operações de E/S etc. Essa estimativa é então convertida em unidades, conhecidas como o custo do plano. O plano com o menor custo é selecionado.

No entanto, à medida que o número de junções aumenta, o número de planos possíveis aumenta exponencialmente. Avaliar todos os planos possíveis torna-se impossível mesmo para consultas relativamente simples. A heurística e os algoritmos são usados para limitar o número de planos possíveis. O resultado é que o plano selecionado pode não ser o plano ideal. Ele será quase ideal, no entanto, e selecionado em um tempo razoável.

O custo é a melhor estimativa do planejador. A finalidade da estimativa de custo é comparar planos de execução diferentes para a mesma consulta nas mesmas condições. O planejador usa estatísticas coletadas em tabelas e linhas para produzir estimativas de custo para consultas. Para que as estimativas de custo sejam precisas, as estatísticas precisam estar atualizadas.

Estatísticas atualizadas

O componente do planejador do otimizador de consulta usa estatísticas sobre tabelas e linhas para produzir estimativas de custo precisas.

O comando ANALYZE coleta estatísticas sobre tabelas de banco de dados e armazena os resultados no catálogo do sistema pg_statistic. Você precisará executar ANALYZE, se:

  • Você desabilitou a aspiração automática (que normalmente analisa tabelas automaticamente)
  • Você desabilitou a aspiração automática e não executou ANALYZE recentemente
  • Um dos anteriores e há muitas instruções INSERTS, UPDATES ou DELETE.

As estimativas de custo respondem a estatísticas atualizadas e, se as estatísticas estiverem desatualizadas, um plano ineficiente poderá ser escolhido. Quando nenhum parâmetro é passado para ANALYZE, todas as tabelas do banco de dados são examinadas.

A sintaxe para ANALYZE é:

ANALYZE [ VERBOSE ] [ ***table*** [ ( ***column*** [, ...] ) ] ]

VERBOSE exibe mensagens de progresso para mostrar qual tabela está sendo analisada, juntamente com algumas estatísticas.

Agende VACUUM e ANALYZE para serem executadas diariamente durante um período de baixo uso. ANALYZE pode ser executada em paralelo com outras atividades, pois requer apenas um bloqueio de leitura na tabela de destino.

Executor

Essa fase usa o plano criado pelo planejador e processa-o recursivamente para extrair o conjunto de linhas necessário. Sempre que um nó de plano é chamado, o executor precisa entregar uma linha ou relatar de volta para informar que ele foi concluído.

O executor avalia todos os quatro tipos de consulta SQL:

  • SELECT
  • INSERT
  • UPDATE
  • DELETE

Para SELECT, o executor retorna cada linha de volta ao cliente como o conjunto de resultados.

Para INSERT, cada linha retornada é inserida na tabela especificada. Isso é feito em um nó de plano especial de nível superior chamado ModifyTable.

Para UPDATE, cada linha computada inclui todos os valores de coluna atualizados, além da ID da linha de destino. Os dados são enviados para um nó ModifyTable, que cria uma linha atualizada e marca a linha antiga como excluída.

Para DELETE, a única coluna que é retornada pelo plano é a ID da linha. O nó ModifyTable usa a ID da linha para marcar a linha como excluída.