Identificar os componentes de processamento de consulta
Há quatro etapas separadas para executar a consulta. Na ordem de execução estas etapas são:
- A Analisar
- Transformação (Reescritor)
- Planeamento
- Execução
O analisador
O analisador é responsável por verificar a seqüência de caracteres de consulta para 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 léxico, que reconhece identificadores e palavras-chave SQL. Cada palavra-chave ou identificador aciona 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.
- Range table entry (RTE) - uma lista de relações,
ie
tabelas, 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 os comandos INSERT, UPDATE e DELETE é a tabela ou exibição onde 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, então o planejador adiciona uma entrada especial para permitir que o executor encontre 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 ou não ser executada. Corresponde à cláusula WHERE de uma instrução SQL.
- Árvore de junção - esta árvore pode ser uma lista dos itens FROM. As junções podem ser feitas em qualquer ordem ou em uma ordem específica, como as 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 regravação , a menos que um erro seja encontrado, caso em que uma mensagem de erro é retornada.
O regravador de consulta reescreve o texto da consulta aplicando regras a ele. O reescritor leva as regras em consideração e, em seguida, 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 fica oculta. Depois que a transação é confirmada, o processo de vácuo pode remover a linha oculta.
Planner
O trabalho do planejador é pegar as regras de consulta e entender qual das diferentes maneiras que a consulta pode ser executada é a mais rápida.
O planejador cria uma árvore de plano, com nós representando 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 custo do plano. O plano com o menor custo é selecionado.
No entanto, à medida que o número de adesões aumenta, o número de planos possíveis cresce exponencialmente. Avaliar todos os planos possíveis torna-se impossível, mesmo para consultas relativamente simples. Heurísticas e algoritmos são usados para limitar o número de planos possíveis. O resultado é que o plano selecionado pode não ser o ideal. É quase ideal, no entanto, e selecionado em um tempo razoável.
O custo é a melhor estimativa do planejador. O objetivo da estimativa de custos é comparar diferentes planos de execução 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 custos sejam precisas, as estatísticas devem estar atualizadas.
Estatísticas atualizadas
O componente planejador do otimizador de consulta usa estatísticas sobre tabelas e linhas para produzir estimativas de custo precisas.
ANALYZE coleta estatísticas sobre tabelas de banco de dados e armazena os resultados no catálogo do sistema pg_statistic . Você precisa executar ANALYZE, se:
- Você desativou o autovacuum (que normalmente analisa as tabelas automaticamente)
- Você desativou o autovacuum e não executou o ANALYZE recentemente
- Qualquer uma das anteriores, e há muitas das instruções INSERTS, UPDATES ou DELETE.
As estimativas de custos baseiam-se em estatísticas atualizadas e, se as estatísticas estiverem desatualizadas e puder ser escolhido um plano ineficiente. Quando nenhum parâmetro é passado para ANALYZE, todas as tabelas no 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.
Programe VACUUM e ANALYZE para funcionar diariamente durante um tempo de baixo uso. ANALYZE pode ser executado em paralelo com outras atividades, pois requer apenas um bloqueio de leitura na tabela de destino.
Executor
Esta fase pega o plano criado pelo planejador e o processa recursivamente para extrair o conjunto necessário de linhas. Cada vez que um nó de plano é chamado, o executor deve entregar uma linha ou relatar para dizer que terminou.
O executor avalia todos os quatro tipos de consulta SQL:
- SELECIONAR
- INSERT
- ATUALIZAR
- 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. Essa tarefa é feita em um nó de plano de nível superior especial chamado ModifyTable.
Para UPDATE, cada linha computada inclui todos os valores de coluna atualizados, além do 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 o ID da linha para marcar a linha como excluída.