PostgreSQL İndeksi Kullanım Analizi


88

Postgres'i analiz etmek ve hangi eksik dizinlerin oluşturulması gerektiğini ve kullanılmayan hangi dizinlerin kaldırılması gerektiğini belirlemek için bir araç veya yöntem var mı? Bunu SQLServer için "profil oluşturucu" aracıyla yaparken biraz deneyimim var, ancak Postgres'te bulunan benzer bir araçtan haberdar değilim.

Yanıtlar:


166

Eksik dizinleri bulmayı seviyorum:

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 than 2%
      AND n_live_tup > 10000
      AND pg_relation_size(relname :: regclass) > 5000000
ORDER BY relname ASC;

Bu, dizin taramalarından daha fazla dizi taraması olup olmadığını kontrol eder. Tablo küçükse, Postgres onlar için sıralı taramaları tercih ettiği için göz ardı edilir.

Yukarıdaki sorgu eksik dizinleri ortaya çıkarır.

Sonraki adım, eksik birleşik dizinleri tespit etmek olacaktır. Sanırım bu kolay değil ama yapılabilir. Belki yavaş sorguları analiz ederken ... pg_stat_statements'ın yardımcı olabileceğini duydum ...


17
Bunun alıntılanan tanımlayıcılarla çalışması için sorguyu şu şekilde değiştirin: 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;
Bay Muskrat

@Cen için, ne zaman too_much_seqolumlu ve büyük olursa endişelenmelisiniz.
mountainclimber11

Tablolardan birinde birkaç dizin oluşturdum, ancak yine de bu sorgu, o tablodaki eksik dizinleri gösteriyor.
Kishore Kumar

1
@KishoreKumar Postgres'teki istatistikler, endeksinizi güncellemeden önce yürütülen sorguları hala içeriyor sanırım. Trafiğinize bağlı olarak istatistikler birkaç saat sonra tekrar normal hale gelecektir.
guettli

1
::regclassbüyük tanımlayıcılarda çalışmaz, @Mr. Muskrat'ın iyi bir çözümü var, onun ('"' || relname || '"')::regclassyerine kullanmak da mümkün .
Adrien


10

Eksik indeksleri belirleme yaklaşımı üzerine .... Hayır. Ancak, sözde dizinler ve makine tarafından okunabilir EXPLAIN gibi gelecekteki sürümde bunu kolaylaştırmak için bazı planlar var.

Şu anda, EXPLAIN ANALYZEkötü performans gösteren sorgular yapmanız ve ardından en iyi rotayı manuel olarak belirlemeniz gerekir. PgFouine gibi bazı günlük analizcileri sorguların belirlenmesine yardımcı olabilir.

Kullanılmayan bir dizine gelince, bunları tanımlamaya yardımcı olması için aşağıdakilere benzer bir şey kullanabilirsiniz:

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

Bu, okunan, taranan, getirilen tupleları tanımlamaya yardımcı olacaktır.


8

PostgreSQL'i analiz etmek için bir başka yeni ve ilginç araç PgHero'dur . Daha çok veri tabanının ayarlanmasına odaklanır ve çok sayıda analiz ve öneri yapar.

ekran görüntüsü


6

Dizin kullanımını ve Dizin boyutunu bulmak için aşağıdaki sorguyu kullanabilirsiniz:

Bu blogdan referans alınmıştır.

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

PostgreSQL wiki'de kullanılmayan dizinleri bulmanıza yardımcı olacak betiklere birden fazla bağlantı vardır . Temel teknik, sorguları yanıtlamak için bu dizinin kaç kez kullanıldığının sıfır olduğu veya en azından çok düşük pg_stat_user_indexesolduğu yerlere bakmak ve aramaktır idx_scan. Uygulama değiştiyse ve daha önce kullanılan bir dizin muhtemelen şimdi değilse, bazen pg_stat_reset()tüm istatistikleri 0'a döndürmek ve sonra yeni veriler toplamak için çalıştırmanız gerekir; her şey için mevcut değerleri kaydedebilir ve bunun yerine bir delta hesaplayabilirsiniz.

Henüz eksik dizinleri önermek için iyi bir araç yok. Bir yaklaşım, çalıştırdığınız sorguları günlüğe kaydetmek ve pgFouine veya pqa gibi bir sorgu günlüğü analiz aracı kullanarak hangilerinin çalıştırılmasının uzun sürdüğünü analiz etmektir. Daha fazla bilgi için " Zor Sorguları Günlüğe Kaydetme " konusuna bakın .

Diğer yaklaşım, pg_stat_user_tablesbüyük olduğu yerlerde çok sayıda ardışık taramaya sahip tablolara bakmak ve aramaktır seq_tup_fetch. Bir indeks kullanıldığında idx_fetch_tupbunun yerine sayı artar. Bu, bir tablonun kendisine yönelik sorguları yanıtlayacak kadar iyi dizine eklenmediğinde size ipucu verebilir.

Aslında hangi sütunları indekslemeniz gerektiğini mi buluyorsunuz? Bu genellikle tekrar sorgu günlüğü analizi şeylerine geri döner.



1

PoWA , PostgreSQL 9.4+ için ilginç bir araç gibi görünüyor. İstatistikleri toplar, görselleştirir ve indeksler önerir. pg_stat_statementsUzantıyı kullanır .

PoWA, PostgreSQL sunucularınızı izlemenize ve ayarlamanıza yardımcı olmak için performans istatistiklerini toplayan ve gerçek zamanlı çizelgeler ve grafikler sağlayan bir PostgreSQL İş Yükü Analizcisi'dir. Oracle AWR veya SQL Server MDW'ye benzer.


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 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.