Analisis Penggunaan Indeks PostgreSQL

89

Apakah ada alat atau metode untuk menganalisis Postgres, dan menentukan indeks apa yang hilang harus dibuat, dan indeks mana yang tidak digunakan harus dihapus? Saya memiliki sedikit pengalaman melakukan ini dengan alat "profiler" untuk SQLServer, tetapi saya tidak mengetahui alat serupa yang disertakan dengan Postgres.

Cerin
sumber
Begitulah. Sudah lama tidak melihat ini. Memperbarui jawaban saya yang diterima.
Cerin

Jawaban:

165

Saya suka ini untuk menemukan indeks yang hilang:

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;

Ini memeriksa apakah ada lebih banyak pemindaian berurutan daripada pemindaian indeks. Jika tabel kecil, itu akan diabaikan, karena Postgres tampaknya lebih suka pemindaian berurutan untuk mereka.

Kueri di atas tidak mengungkapkan indeks yang hilang.

Langkah selanjutnya adalah mendeteksi indeks gabungan yang hilang. Saya rasa ini tidak mudah, tapi bisa dilakukan. Mungkin menganalisis kueri yang lambat ... Saya dengar pg_stat_statements dapat membantu ...

guettli
sumber
17
Untuk membuat ini berfungsi dengan pengidentifikasi yang dikutip, ubah kueri menjadi: 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;
Tn. Muskrat
10
Keluaran dari kueri ini harus dijelaskan agar jawabannya lebih bermanfaat
cen
Untuk poin @cen, kapan too_much_seqpositif dan besar Anda harus peduli.
mountainclimber11
1
@KishoreKumar Saya kira statistik di postgres masih berisi kueri yang dieksekusi sebelum Anda memperbarui indeks Anda. Bergantung pada lalu lintas Anda, statistik akan baik-baik saja setelah beberapa jam.
guettli
1
::regclasstidak akan berfungsi pada pengidentifikasi huruf besar, @Mr. Muskrat memiliki solusi yang baik, itu juga mungkin untuk digunakan ('"' || relname || '"')::regclasssebagai gantinya.
Adrien
21

Periksa statistiknya. pg_stat_user_tablesdan pg_stat_user_indexesyang akan memulai.

Lihat " The Statistics Collector ".

Frank Heikens
sumber
10

Pada pendekatan menentukan indeks yang hilang .... Tidak. Namun ada beberapa rencana untuk membuatnya lebih mudah di rilis mendatang, seperti indeks semu dan JELASKAN yang dapat dibaca mesin.

Saat ini, Anda perlu EXPLAIN ANALYZEkueri yang berkinerja buruk dan kemudian secara manual menentukan rute terbaik. Beberapa penganalisis log seperti pgFouine dapat membantu menentukan kueri.

Sejauh indeks yang tidak terpakai, Anda dapat menggunakan sesuatu seperti berikut untuk membantu mengidentifikasinya:

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

Ini akan membantu mengidentifikasi tupel yang dibaca, dipindai, diambil.

rfusca.dll
sumber
Frank Heikens juga menunjukkan beberapa tempat bagus lainnya untuk menanyakan tentang penggunaan indeks saat ini.
rfusca
8

Alat baru dan menarik lainnya untuk menganalisis PostgreSQL adalah PgHero . Ini lebih difokuskan pada penyetelan database dan membuat banyak analisis dan saran.

tangkapan layar

n1000
sumber
6

Anda dapat menggunakan kueri di bawah ini untuk menemukan penggunaan Indeks dan ukuran Indeks:

Referensi diambil dari blog ini.

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
sumber
4

Ada beberapa tautan ke skrip yang akan membantu Anda menemukan indeks yang tidak digunakan di wiki PostgreSQL . Teknik dasarnya adalah melihat pg_stat_user_indexesdan mencari yang mana idx_scan, hitungan berapa kali indeks itu digunakan untuk menjawab pertanyaan, adalah nol, atau setidaknya sangat rendah. Jika aplikasi telah berubah dan indeks yang sebelumnya digunakan mungkin tidak sekarang, terkadang Anda harus menjalankan pg_stat_reset()untuk mengembalikan semua statistik ke 0 dan kemudian mengumpulkan data baru; Anda dapat menyimpan nilai saat ini untuk semuanya dan menghitung delta sebagai gantinya untuk mencari tahu.

Belum ada alat bagus yang tersedia untuk menyarankan indeks yang hilang. Salah satu pendekatannya adalah mencatat kueri yang Anda jalankan dan menganalisis kueri mana yang membutuhkan waktu lama untuk dijalankan menggunakan alat analisis log kueri seperti pgFouine atau pqa. Lihat " Mencatat Kueri Sulit " untuk info lebih lanjut.

Pendekatan lainnya adalah dengan melihat pg_stat_user_tablesdan mencari tabel yang memiliki sejumlah besar pemindaian berurutan, yang ukurannya seq_tup_fetchbesar. Ketika sebuah indeks digunakan, idx_fetch_tuphitungannya meningkat. Itu bisa memberi petunjuk kepada Anda ketika tabel tidak diindeks dengan cukup baik untuk menjawab pertanyaan terhadapnya.

Sebenarnya mencari tahu kolom mana yang harus Anda indeks? Itu biasanya mengarah kembali ke hal-hal analisis log kueri lagi.

Greg Smith
sumber
1

PoWA sepertinya alat yang menarik untuk PostgreSQL 9.4+. Ini mengumpulkan statistik, memvisualisasikannya, dan menyarankan indeks. Ini menggunakan pg_stat_statementsekstensi.

PoWA adalah Penganalisis Beban Kerja PostgreSQL yang mengumpulkan statistik kinerja dan menyediakan bagan dan grafik waktu nyata untuk membantu memantau dan menyesuaikan server PostgreSQL Anda. Ini mirip dengan Oracle AWR atau SQL Server MDW.

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

Ini akan membantu: Analisis Query Pratical

João Pereira
sumber
1
Pembaruan terakhir PQA berumur beberapa tahun. Apakah ini fitur yang tidak didukung oleh pgFouine?
guettli