Análise de uso do índice PostgreSQL


87

Existe uma ferramenta ou método para analisar o Postgres e determinar quais índices ausentes devem ser criados e quais índices não utilizados devem ser removidos? Tenho um pouco de experiência em fazer isso com a ferramenta "profiler" para SQLServer, mas não conheço uma ferramenta semelhante incluída no Postgres.


Então é. Não vejo isso há algum tempo. Atualizei minha resposta aceita.
Cerin

Respostas:


164

Eu gosto disso para encontrar índices ausentes:

SELECT
  relname                                               AS TableName,
  to_char(seq_scan, '999,999,999,999')                  AS TotalSeqScan,
  to_char(idx_scan, '999,999,999,999')                  AS TotalIndexScan,
  to_char(n_live_tup, '999,999,999,999')                AS TableRows,
  pg_size_pretty(pg_relation_size(relname :: regclass)) AS TableSize
FROM pg_stat_all_tables
WHERE schemaname = 'public'
      AND 50 * seq_scan > idx_scan -- more then 2%
      AND n_live_tup > 10000
      AND pg_relation_size(relname :: regclass) > 5000000
ORDER BY relname ASC;

Isso verifica se há mais varreduras de sequência do que varreduras de índice. Se a tabela for pequena, ela será ignorada, já que o Postgres parece preferir varreduras de sequência para eles.

A consulta acima revela índices ausentes.

A próxima etapa seria detectar índices combinados ausentes. Acho que não é fácil, mas é possível. Talvez analisar as consultas lentas ... Ouvi dizer que pg_stat_statements pode ajudar ...


15
Para fazer isso funcionar com os identificadores entre aspas, altere a consulta para: SELECT relname, seq_scan-idx_scan AS too_much_seq, case when seq_scan-idx_scan>0 THEN 'Missing Index?' ELSE 'OK' END, pg_relation_size(relid::regclass) AS rel_size, seq_scan, idx_scan FROM pg_stat_all_tables WHERE schemaname='public' AND pg_relation_size(relid::regclass)>80000 ORDER BY too_much_seq DESC;
Sr. Muskrat

10
A saída desta consulta deve ser explicado para tornar a resposta mais útil
cen

Para o ponto de @cen, quando too_much_seqé positivo e grande, você deve se preocupar.
mountainclimber11

1
@KishoreKumar Acho que as estatísticas no postgres ainda contêm as consultas que foram executadas antes de você atualizar seu índice. Dependendo do seu tráfego, as estatísticas estarão ok novamente após algumas horas.
guettli de

1
::regclassnão funcionará em identificadores em maiúsculas, @Mr. Muskrat tem uma boa solução, também é possível usar em seu ('"' || relname || '"')::regclasslugar.
Adrien


10

Sobre a abordagem de determinação de índices ausentes .... Não. Mas há alguns planos para tornar isso mais fácil em versões futuras, como pseudo-índices e EXPLAIN legível por máquina.

Atualmente, você precisará EXPLAIN ANALYZEfazer consultas de baixo desempenho e, em seguida, determinar manualmente a melhor rota. Alguns analisadores de log, como o pgFouine podem ajudar a determinar as consultas.

No que diz respeito a um índice não utilizado, você pode usar algo como o seguinte para ajudar a identificá-los:

select * from pg_stat_all_indexes where schemaname <> 'pg_catalog';

Isso ajudará a identificar tuplas lidas, verificadas, buscadas.


Frank Heikens também aponta alguns bons lugares para consultar sobre o uso atual do índice.
rfusca

8

Outra ferramenta nova e interessante para analisar PostgreSQL é o PgHero . Está mais focado em ajustar o banco de dados e faz inúmeras análises e sugestões.

captura de tela


6

Você pode usar a consulta abaixo para encontrar o uso e o tamanho do índice:

A referência é tirada deste blog.

SELECT
    pt.tablename AS TableName
    ,t.indexname AS IndexName
    ,to_char(pc.reltuples, '999,999,999,999') AS TotalRows
    ,pg_size_pretty(pg_relation_size(quote_ident(pt.tablename)::text)) AS TableSize
    ,pg_size_pretty(pg_relation_size(quote_ident(t.indexrelname)::text)) AS IndexSize
    ,to_char(t.idx_scan, '999,999,999,999') AS TotalNumberOfScan
    ,to_char(t.idx_tup_read, '999,999,999,999') AS TotalTupleRead
    ,to_char(t.idx_tup_fetch, '999,999,999,999') AS TotalTupleFetched
FROM pg_tables AS pt
LEFT OUTER JOIN pg_class AS pc 
    ON pt.tablename=pc.relname
LEFT OUTER JOIN
( 
    SELECT 
        pc.relname AS TableName
        ,pc2.relname AS IndexName
        ,psai.idx_scan
        ,psai.idx_tup_read
        ,psai.idx_tup_fetch
        ,psai.indexrelname 
    FROM pg_index AS pi
    JOIN pg_class AS pc 
        ON pc.oid = pi.indrelid
    JOIN pg_class AS pc2 
        ON pc2.oid = pi.indexrelid
    JOIN pg_stat_all_indexes AS psai 
        ON pi.indexrelid = psai.indexrelid 
)AS T
    ON pt.tablename = T.TableName
WHERE pt.schemaname='public'
ORDER BY 1;

4

Existem vários links para scripts que o ajudarão a encontrar índices não usados ​​no wiki do PostgreSQL . A técnica básica é olhar pg_stat_user_indexese procurar aqueles em que idx_scana contagem de quantas vezes esse índice foi usado para responder a consultas é zero ou pelo menos muito baixo. Se o aplicativo foi alterado e um índice usado anteriormente provavelmente não mudou agora, às vezes você precisa executar pg_stat_reset()para obter todas as estatísticas de volta para 0 e, em seguida, coletar novos dados; você pode salvar os valores atuais para tudo e calcular um delta em vez de descobrir isso.

Ainda não existem boas ferramentas disponíveis para sugerir índices ausentes. Uma abordagem é registrar as consultas que você está executando e analisar quais estão demorando muito para serem executadas usando uma ferramenta de análise de log de consultas como pgFouine ou pqa. Consulte " Registro de consultas difíceis " para obter mais informações.

A outra abordagem é examinar pg_stat_user_tablese procurar tabelas que tenham um grande número de varreduras sequenciais, onde seq_tup_fetché grande. Quando um índice é usado, a idx_fetch_tupcontagem é aumentada. Isso pode indicar quando uma tabela não está indexada o suficiente para responder a consultas em relação a ela.

Na verdade, descobrindo em quais colunas você deve indexar? Isso geralmente leva de volta ao material de análise de log de consulta novamente.



1

O PoWA parece uma ferramenta interessante para PostgreSQL 9.4+. Ele coleta estatísticas, as visualiza e sugere índices. Ele usa a pg_stat_statementsextensão.

PoWA é o PostgreSQL Workload Analyzer que reúne estatísticas de desempenho e fornece gráficos e tabelas em tempo real para ajudar a monitorar e ajustar seus servidores PostgreSQL. É semelhante ao Oracle AWR ou SQL Server MDW.


0
CREATE EXTENSION pgstattuple; 
CREATE TABLE test(t INT); 
INSERT INTO test VALUES(generate_series(1, 100000)); 
SELECT * FROM pgstatindex('test_idx'); 

version            | 2 
tree_level         | 2 
index_size         | 105332736 
root_block_no      | 412 
internal_pages     | 40 
leaf_pages         | 12804 
empty_pages        | 0 
deleted_pages      | 13 
avg_leaf_density   | 9.84 
leaf_fragmentation | 21.42 

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.