Conforme visto na seção anterior, o planejador de comandos precisa estimar o número de linhas buscadas pelo comando para poder fazer boas escolhas dos planos de comando. Esta seção fornece uma rápida visão das estatísticas utilizadas pelo sistema para fazer estas estimativas.
Um dos componentes da estatística é o número total de entradas em cada tabela e índice, assim como o número de blocos de disco ocupados por cada tabela e índice. Esta informação é mantida nas colunas reltuples e relpages da tabela pg_class, podendo ser vista utilizando consultas semelhantes à mostrada abaixo:
SELECT relname, relkind, reltuples, relpages FROM pg_class WHERE relname LIKE 'tenk1%'; relname | relkind | reltuples | relpages ---------------+---------+-----------+---------- tenk1 | r | 10000 | 233 tenk1_hundred | i | 10000 | 30 tenk1_unique1 | i | 10000 | 30 tenk1_unique2 | i | 10000 | 30 (4 linhas)
Pode ser visto que tenk1 contém 10.000 linhas, assim como seus índices, mas que os índices são (sem surpresa) muito menores que a tabela.
Por razões de eficiência, as colunas reltuples e relpages não são atualizadas dinamicamente e, portanto, usualmente contêm valores um pouco desatualizados. São atualizadas pelos comandos VACUUM, ANALYZE e uns poucos comandos de DDL como CREATE INDEX. Um comando ANALYZE autônomo, ou seja, não fazendo parte do VACUUM, gera um valor aproximado para reltuples uma vez que não lê todas as linhas da tabela. O planejador faz uma proporcionalidade dos valores encontrados em pg_class para que correspondam ao tamanho físico corrente da tabela, obtendo assim uma estimativa mais próxima.
A maioria dos comandos busca apenas uma fração das linhas da tabela, porque possuem cláusulas WHERE que restringem as linhas a serem examinadas. Portanto, o planejador precisa fazer uma estimativa da seletividade das cláusulas WHERE, ou seja, a fração das linhas correspondendo a cada condição na cláusula WHERE. A informação utilizada para esta tarefa é armazenada no catálogo do sistema pg_statistic. As entradas em pg_statistic são atualizadas pelos comandos ANALYZE e VACUUM ANALYZE, sendo sempre aproximadas, mesmo logo após serem atualizadas.
Em vez de olhar diretamente em pg_statistic, é melhor olhar sua visão pg_stats ao se examinar as estatísticas manualmente. A visão pg_stats foi projetada para ser lida mais facilmente. Além disso, pg_stats pode ser lida por todos, enquanto pg_statistic somente pode ser lida pelos superusuários (Isto impede que usuários não privilegiados aprendam algo sobre o conteúdo das tabelas de outras pessoas a partir de suas estatísticas. A visão pg_stats tem como restrição mostrar somente informações sobre as tabelas que o usuário corrente pode ler). Por exemplo, podemos executar:
SELECT attname, n_distinct, most_common_vals FROM pg_stats WHERE tablename = 'road'; attname | n_distinct | most_common_vals ---------+------------+--------------------------------------------- name | -0.467008 | {"I- 580 Ramp", ... } thepath | 20 | {"[(-122.089,37.71),(-122.0886,37.711)]"} (2 linhas) /* * onde ... representa: * "I- 880 Ramp", * "Sp Railroad ", * "I- 580 ", * "I- 680 Ramp", * "I- 80 Ramp", * "14th St ", * "5th St ", * "Mission Blvd", * "I- 880 " */
A visão pg_stats está descrita detalhadamente na Seção 42.36.
A quantidade de informação armazenada em pg_statistic, em particular o número máximo de entradas nas matrizes most_common_vals e histogram_bounds para cada coluna, podem ser definidas coluna por coluna utilizando o comando ALTER TABLE SET STATISTICS, ou globalmente definindo a variável de configuração default_statistics_target. Atualmente o limite padrão são 10 entradas. Aumentar o limite pode permitir que o planejador faça estimativas mais precisas, particularmente para colunas com distribuição irregular dos dados, porém consumindo mais espaço na tabela pg_statistic e um pouco mais de tempo para computar as estimativas. Inversamente, um limite mais baixo pode ser apropriado para colunas com distribuição dos dados simples.