Eu uso este snippet para detectar índices ausentes:
https://stackoverflow.com/a/12818168/633961
Exemplo:
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;
Resultado:
tablename | totalseqscan | totalindexscan | tablerows | tablesize
----------+--------------+----------------+-----------+----------
mytable | 112,479 | 2,978,344 | 1,293,536 | 1716 MB
Estou curioso - gostaria de ver quais instruções SQL realmente fazem uma varredura seq na tabela mytable
.
Existe uma maneira de deixar o PostgreSQL emitir um aviso se ele fizer uma varredura sequencial nesta tabela?
Eu acho que a única maneira de fazer isso é usar o módulo auto_explain e habilitar o despejo de planos de execução se uma instrução for mais lenta que, por exemplo, um segundo.
O plano será gravado no arquivo de log do Postgres
Então você pode ter um trabalho que monitore o arquivo de log e execute ações se uma Seq Scan fizer parte do plano.
Um Seq Scan não é algo que deve ser evitado a todo custo. Muitas vezes é a maneira mais rápida de obter o resultado.
Eu me concentraria em planos com Seq Scans, mas simplesmente tentaria encontrar (e depois corrigir) consultas lentas.
Para analisar o arquivo de log, você deseja ter um log no pgbadger ou pode usar o POWA para monitorar seu servidor em tempo real