Identificar os componentes de processamento de consulta
Há quatro estágios separados para executar a consulta. Na ordem de execução, esses estágios são:
- Análise
- Transformação (Reescrita)
- Planeamento
- Execução
O analisador
O analisador é responsável por verificar a cadeia de caracteres de consulta em busca de 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 do lexer, que reconhece identificadores e palavras-chave 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 dos comandos INSERT, UPDATE e DELETE é a tabela ou vista em que as alterações devem ter efeito.
- 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 resultados. Para comandos UPDATE, a lista de destino descreve as novas linhas que devem substituir as antigas.
- Qualificação – um valor booleano que especifica se a operação para a linha de resultado final deve ser executada ou não. Corresponde à cláusula WHERE de uma instrução SQL.
- Árvore de Junção - essa árvore pode ser uma lista dos itens de 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 neste estágio, como a cláusula ORDER BY.
Regravador
A saída do analisador é passada para a transformação ou o processo de regravador, a menos que um erro seja encontrado, caso em que uma mensagem de erro é retornada.
O reescritor de consultas reescreve a consulta ao aplicar regras a ela. O regravador 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 neste estágio.
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 está oculta. Após a confirmação da transação, o processo de vácuo pode remover a linha oculta.
Planejador
O trabalho do planejador é pegar as regras de consulta e entender quais das diferentes maneiras pelas quais a consulta pode ser executada é a mais rápida.
O planejador cria uma árvore de planos, 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 exigidos são necessários, como ciclos de CPU, operações de E/S etc. Essa estimativa é então convertida em unidades, conhecidas como 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. É 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 de . O planejador usa estatísticas coletadas em tabelas e linhas para produzir estimativas de custo para consultas. Para que as estimativas de custos sejam precisas, as estatísticas devem estar atualizadas.
Estatísticas atualizadas
O componente planner do otimizador de consulta usa estatísticas sobre tabelas e linhas para produzir estimativas de custo precisas.
O 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 o autovacuum (que normalmente analisa tabelas automaticamente)
- Você desabilitou de vácuo automático e não executou o ANALYZE recentemente
- Qualquer um dos anteriores, e há muitas instruções de INSERT, UPDATE ou DELETE.
As estimativas de custo dependem up-toestatísticas de data e se as estatísticas estiverem desatualizadas e um plano ineficiente puder 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 executados diariamente durante um tempo de baixo uso. O ANALYZE pode ser executado 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 o processa recursivamente para extrair o conjunto de linhas necessário. Sempre que um nó de plano é chamado, o executor deve entregar uma linha ou comunicar que terminou.
O executor avalia todos os quatro tipos de consulta SQL:
- SELECIONAR
- INSERIR
- ATUALIZAÇÃO
- EXCLUIR
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. Esta tarefa é realizada em um nó especial de plano 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 retornada pelo plano é a ID da linha. O nó ModifyTable usa a ID da linha para marcar a linha como excluída.