Análisis de uso del índice de PostgreSQL

87

¿Existe una herramienta o método para analizar Postgres y determinar qué índices faltantes deben crearse y qué índices no utilizados deben eliminarse? Tengo un poco de experiencia haciendo esto con la herramienta "profiler" para SQLServer, pero no conozco una herramienta similar incluida con Postgres.

Cerin
fuente
Así es. No he mirado esto por un tiempo. Actualicé mi respuesta aceptada.
Cerin

Respuestas:

164

Me gusta esto para encontrar índices faltantes:

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;

Esto comprueba si hay más exploraciones de secuencia que exploraciones de índice. Si la tabla es pequeña, se ignora, ya que Postgres parece preferir los escaneos de secuencia para ellos.

La consulta anterior revela índices faltantes.

El siguiente paso sería detectar índices combinados faltantes. Supongo que esto no es fácil, pero factible. Tal vez analizando las consultas lentas ... Escuché que pg_stat_statements podría ayudar ...

guettli
fuente
15
Para que esto funcione con identificadores entre comillas, cambie la consulta a: 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;
Mr. Muskrat
10
El resultado de esta consulta debe explicarse para que la respuesta sea más útil
cen
Para el punto de @cen, cuando too_much_seqes positivo y grande debes preocuparte.
mountainclimber11
1
@KishoreKumar Supongo que las estadísticas en postgres todavía contienen las consultas que se ejecutaron antes de actualizar su índice. Dependiendo de su tráfico, las estadísticas volverán a estar bien después de algunas horas.
guettli
1
::regclassno funcionará con identificadores en mayúsculas, @Mr. La rata almizclera tiene una buena solución, también es posible usarla ('"' || relname || '"')::regclassen su lugar.
Adrien
10

En el enfoque de determinar los índices faltantes ... Nop. Pero hay algunos planes para facilitar esto en versiones futuras, como pseudoíndices y EXPLAIN legible por máquina.

Actualmente, deberá EXPLAIN ANALYZErealizar consultas de bajo rendimiento y luego determinar manualmente la mejor ruta. Algunos analizadores de registros como pgFouine pueden ayudar a determinar las consultas.

En cuanto a un índice no utilizado, puede utilizar algo como lo siguiente para ayudar a identificarlos:

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

Esto ayudará a identificar las tuplas leídas, escaneadas y recuperadas.

rfusca
fuente
Frank Heikens también señala algunos buenos lugares en otros lugares para consultar sobre el uso actual de índices.
rfusca
8

Otra nueva e interesante herramienta para analizar PostgreSQL es PgHero . Se centra más en ajustar la base de datos y realiza numerosos análisis y sugerencias.

captura de pantalla

n1000
fuente
6

Puede utilizar la siguiente consulta para encontrar el uso del índice y el tamaño del índice:

La referencia se toma de este 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
fuente
4

Hay varios enlaces a scripts que le ayudarán a encontrar índices no utilizados en la wiki de PostgreSQL . La técnica básica es mirar pg_stat_user_indexesy buscar aquellos en los que idx_scanel recuento de cuántas veces se ha utilizado ese índice para responder consultas es cero, o al menos muy bajo. Si la aplicación ha cambiado y un índice usado anteriormente probablemente no lo esté ahora, a veces debe ejecutar pg_stat_reset()para que todas las estadísticas vuelvan a 0 y luego recopilar nuevos datos; puede guardar los valores actuales para todo y calcular un delta en su lugar para averiguarlo.

Todavía no hay buenas herramientas disponibles para sugerir índices faltantes. Un enfoque es registrar las consultas que está ejecutando y analizar cuáles tardan mucho en ejecutarse utilizando una herramienta de análisis de registro de consultas como pgFouine o pqa. Consulte " Registro de consultas difíciles " para obtener más información.

El otro enfoque es mirar pg_stat_user_tablesy buscar tablas que tengan un gran número de escaneos secuenciales, donde seq_tup_fetchsea ​​grande. Cuando se usa un índice, el idx_fetch_tuprecuento aumenta. Eso puede indicarle cuándo una tabla no está indexada lo suficientemente bien como para responder consultas en su contra.

¿Realmente averiguar en qué columnas debería indexar? Eso suele llevar de nuevo al análisis del registro de consultas.

Greg Smith
fuente
1

PoWA parece una herramienta interesante para PostgreSQL 9.4+. Recopila estadísticas, las visualiza y sugiere índices. Utiliza la pg_stat_statementsextensión.

PoWA es el analizador de carga de trabajo de PostgreSQL que recopila estadísticas de rendimiento y proporciona tablas y gráficos en tiempo real para ayudar a monitorear y ajustar sus servidores PostgreSQL. Es similar a Oracle AWR o SQL Server MDW.

n1000
fuente
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
fuente
-1

Esto debería ayudar: Análisis práctico de consultas

João Pereira
fuente
1
La última actualización de PQA tiene varios años. ¿Tiene una función que no es compatible con pgFouine?
guettli