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.

Cerin
fonte
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 ...

Guettli
fonte
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
21

Verifique as estatísticas. pg_stat_user_tablese pg_stat_user_indexessão os primeiros.

Vejo " O Coletor de Estatísticas ".

Frank Heikens
fonte
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.

rfusca
fonte
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

n1000
fonte
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;
Anvesh
fonte
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.

Greg Smith
fonte
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.

n1000
fonte
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 
madjardi
fonte
-1

Isso deve ajudar: Análise de consulta prática

João pereira
fonte
1
A última atualização do PQA tem vários anos. Possui um recurso que não é compatível com o pgFouine?
guettli de