การวิเคราะห์การใช้ดัชนี PostgreSQL


89

มีเครื่องมือหรือวิธีการวิเคราะห์ Postgres หรือไม่และควรสร้างดัชนีที่ขาดหายไปและควรลบดัชนีใดที่ไม่ได้ใช้ออกไป ฉันมีประสบการณ์เล็กน้อยในการทำเช่นนี้กับเครื่องมือ "profiler" สำหรับ SQLServer แต่ฉันไม่ทราบว่ามีเครื่องมือที่คล้ายกันที่มาพร้อมกับ Postgres


ดังนั้นจึงเป็น ยังไม่ได้ดูสิ่งนี้ในชั่วขณะ อัปเดตคำตอบที่ยอมรับของฉัน
Cerin

คำตอบ:


165

ฉันชอบสิ่งนี้เพื่อค้นหาดัชนีที่ขาดหายไป:

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;

ตรวจสอบว่ามีการสแกนลำดับเพิ่มเติมหรือไม่จากนั้นจึงทำการสแกนดัชนี หากตารางมีขนาดเล็กตารางจะถูกเพิกเฉยเนื่องจาก Postgres ดูเหมือนว่าจะชอบการสแกนตามลำดับมากกว่า

แบบสอบถามด้านบนแสดงดัชนีที่ขาดหายไป

ขั้นตอนต่อไปคือการตรวจหาดัชนีรวมที่ขาดหายไป ฉันเดาว่านี่ไม่ใช่เรื่องง่าย แต่ทำได้ บางทีการวิเคราะห์คำค้นหาที่ช้า ... ฉันได้ยินมาว่าpg_stat_statementsสามารถช่วยได้ ...


17
เพื่อให้สามารถใช้งานได้กับตัวระบุที่ยกมาให้เปลี่ยนคำถามเป็น: 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;
นายมัสก์รัตน์

10
ควรอธิบายผลลัพธ์ของแบบสอบถามนี้เพื่อให้คำตอบมีประโยชน์มากขึ้น
cen

ในประเด็นของ @cen เมื่อใดที่too_much_seqเป็นบวกและใหญ่คุณควรกังวล
mountainclimber11

1
@KishoreKumar ฉันเดาว่าสถิติใน postgres ยังคงมีการสืบค้นที่ดำเนินการก่อนที่คุณจะอัปเดตดัชนีของคุณ สถิติจะใช้ได้อีกครั้งหลังจากผ่านไปหลายชั่วโมงทั้งนี้ขึ้นอยู่กับการเข้าชม
guettli

1
::regclassจะไม่ทำงานกับตัวระบุตัวพิมพ์ใหญ่ @Mr Muskrat มีทางออกที่ดีและยังสามารถใช้('"' || relname || '"')::regclassแทนได้
Adrien


10

เกี่ยวกับแนวทางการกำหนดดัชนีที่ขาดหายไป .... แต่มีแผนที่จะทำให้สิ่งนี้ง่ายขึ้นในรุ่นต่อ ๆ ไปเช่นดัชนีหลอกและ EXPLAIN ที่เครื่องอ่านได้

ขณะนี้คุณจะต้องEXPLAIN ANALYZEค้นหาคำค้นหาที่มีประสิทธิภาพต่ำจากนั้นจึงกำหนดเส้นทางที่ดีที่สุดด้วยตนเอง เครื่องวิเคราะห์บันทึกบางอย่างเช่นpgFouineสามารถช่วยกำหนดแบบสอบถามได้

สำหรับดัชนีที่ไม่ได้ใช้คุณสามารถใช้สิ่งต่อไปนี้เพื่อช่วยระบุดัชนีได้:

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

สิ่งนี้จะช่วยระบุสิ่งที่ถูกอ่านสแกนดึงข้อมูล


Frank Heikens ยังชี้ให้เห็นถึงสถานที่ดีๆอื่น ๆ ในการสอบถามเกี่ยวกับการใช้ดัชนีปัจจุบัน
rfusca

8

อีกหนึ่งเครื่องมือที่ใหม่และน่าสนใจสำหรับการวิเคราะห์ PostgreSQL เป็นPgHero มุ่งเน้นไปที่การปรับแต่งฐานข้อมูลและทำการวิเคราะห์และข้อเสนอแนะมากมาย

ภาพหน้าจอ


6

คุณสามารถใช้แบบสอบถามด้านล่างเพื่อค้นหาการใช้ดัชนีและขนาดดัชนี:

ข้อมูลอ้างอิงนำมาจากบล็อกนี้

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 เทคนิคพื้นฐานคือการดูpg_stat_user_indexesและค้นหาidx_scanว่ามีการใช้ดัชนีกี่ครั้งในการตอบคำถามเป็นศูนย์หรืออย่างน้อยก็ต่ำมาก หากแอปพลิเคชันมีการเปลี่ยนแปลงและดัชนีที่ใช้ก่อนหน้านี้อาจไม่อยู่ในขณะนี้บางครั้งคุณต้องเรียกใช้pg_stat_reset()เพื่อให้สถิติทั้งหมดกลับมาเป็น 0 จากนั้นรวบรวมข้อมูลใหม่ คุณอาจบันทึกค่าปัจจุบันสำหรับทุกอย่างและคำนวณเดลต้าแทนเพื่อหาค่านั้น

ยังไม่มีเครื่องมือที่ดีที่จะแนะนำดัชนีที่ขาดหายไป แนวทางหนึ่งคือบันทึกการสืบค้นที่คุณกำลังเรียกใช้และวิเคราะห์ว่าคำค้นหาใดใช้เวลานานในการเรียกใช้โดยใช้เครื่องมือวิเคราะห์บันทึกการสืบค้นเช่น pgFouine หรือ pqa ดู " การบันทึกข้อความค้นหาที่ยาก " สำหรับข้อมูลเพิ่มเติม

อีกวิธีหนึ่งคือการดูpg_stat_user_tablesและมองหาตารางที่มีการสแกนตามลำดับจำนวนมากซึ่งseq_tup_fetchมีขนาดใหญ่ เมื่อใช้ดัชนีidx_fetch_tupจำนวนจะเพิ่มขึ้นแทน สิ่งนี้สามารถบอกคุณได้เมื่อตารางไม่ได้รับการจัดทำดัชนีที่ดีพอที่จะตอบคำถามกับมัน

จริงๆแล้วคิดว่าคอลัมน์ใดที่คุณควรจัดทำดัชนี? ซึ่งมักจะนำกลับไปสู่การวิเคราะห์บันทึกการสืบค้นอีกครั้ง



1

PoWAดูเหมือนจะเป็นเครื่องมือที่น่าสนใจสำหรับ PostgreSQL 9.4+ รวบรวมสถิติแสดงภาพและแนะนำดัชนี มันใช้pg_stat_statementsส่วนขยาย

PoWA คือ PostgreSQL Workload Analyzer ที่รวบรวมสถิติประสิทธิภาพและจัดเตรียมแผนภูมิและกราฟแบบเรียลไทม์เพื่อช่วยตรวจสอบและปรับแต่งเซิร์ฟเวอร์ PostgreSQL ของคุณ คล้ายกับ Oracle AWR หรือ SQL Server MDW


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 

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.