Phân tích sử dụng chỉ mục PostgreSQL


86

Có công cụ hoặc phương pháp nào để phân tích Postgres, và xác định những chỉ mục nào bị thiếu nên được tạo và những chỉ mục nào không sử dụng nên được loại bỏ? Tôi có một chút kinh nghiệm làm việc này với công cụ "hồ sơ" cho SQLServer, nhưng tôi không biết về một công cụ tương tự đi kèm với Postgres.


Nên nó là. Tôi đã không nhìn vào điều này trong một thời gian. Đã cập nhật câu trả lời được chấp nhận của tôi.
Cerin

Câu trả lời:


164

Tôi thích điều này để tìm các chỉ mục bị thiếu:

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;

Điều này sẽ kiểm tra xem có nhiều lần quét theo trình tự hơn không sau đó quét chỉ mục. Nếu bảng nhỏ, nó sẽ bị bỏ qua, vì Postgres có vẻ thích quét theo trình tự hơn cho chúng.

Truy vấn trên không tiết lộ các chỉ mục bị thiếu.

Bước tiếp theo sẽ là phát hiện các chỉ mục kết hợp bị thiếu. Tôi đoán điều này không dễ dàng, nhưng có thể làm được. Có thể đang phân tích các truy vấn chậm ... Tôi nghe nói pg_stat_statements có thể giúp ...


15
Để làm cho điều này hoạt động với các số nhận dạng được trích dẫn, hãy thay đổi truy vấn thành: 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;
Ông Muskrat

10
Kết quả đầu ra của truy vấn này nên được giải thích để làm cho câu trả lời hữu ích hơn
cen

Theo quan điểm của @cen, too_much_seqbạn nên quan tâm khi nào là tích cực và lớn.
Mountainclimber

1
@KishoreKumar Tôi đoán số liệu thống kê trong postgres vẫn chứa các truy vấn được thực thi trước khi bạn cập nhật chỉ mục của mình. Tùy thuộc vào lưu lượng truy cập của bạn, số liệu thống kê sẽ ổn định trở lại sau vài giờ.
guettli

1
::regclasssẽ không hoạt động trên các số nhận dạng viết hoa, @Mr. Muskrat có một giải pháp tốt, nó cũng có thể sử dụng ('"' || relname || '"')::regclassthay thế.
Adrien


10

Về phương pháp xác định các chỉ mục bị thiếu .... Không. Nhưng có một số kế hoạch để làm cho điều này dễ dàng hơn trong bản phát hành trong tương lai, chẳng hạn như chỉ mục giả và máy có thể đọc được GIẢI THÍCH.

Hiện tại, bạn sẽ cần EXPLAIN ANALYZEthực hiện các truy vấn hoạt động kém và sau đó xác định tuyến đường tốt nhất theo cách thủ công. Một số công cụ phân tích nhật ký như pgFouine có thể giúp xác định các truy vấn.

Đối với một chỉ mục không được sử dụng, bạn có thể sử dụng một số thứ như sau để giúp xác định chúng:

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

Điều này sẽ giúp xác định các bộ giá trị đã đọc, đã quét, đã tìm nạp.


Frank Heikens cũng chỉ ra một số địa điểm tốt khác để truy vấn về việc sử dụng chỉ mục hiện tại.
rfusca

8

Một công cụ mới và thú vị khác để phân tích PostgreSQL là PgHero . Nó tập trung hơn vào việc điều chỉnh cơ sở dữ liệu và đưa ra nhiều phân tích và đề xuất.

ảnh chụp màn hình


6

Bạn có thể sử dụng truy vấn dưới đây để tìm cách sử dụng Chỉ mục và kích thước Chỉ mục:

Tham khảo được lấy từ blog này.

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

Có nhiều liên kết đến các tập lệnh sẽ giúp bạn tìm các chỉ mục không sử dụng tại wiki PostgreSQL . Kỹ thuật cơ bản là xem xét pg_stat_user_indexesvà tìm kiếm những chỉ mục mà ở đó idx_scan, số lần chỉ mục đó đã được sử dụng để trả lời các truy vấn, bằng 0 hoặc ít nhất là rất thấp. Nếu ứng dụng đã thay đổi và chỉ mục được sử dụng trước đây có lẽ không còn nữa, đôi khi bạn phải chạy pg_stat_reset()để đưa tất cả các thống kê về 0 và sau đó thu thập dữ liệu mới; bạn có thể lưu các giá trị hiện tại cho mọi thứ và thay vào đó tính toán delta để tìm ra điều đó.

Hiện chưa có bất kỳ công cụ tốt nào để đề xuất các chỉ mục bị thiếu. Một cách tiếp cận là ghi nhật ký các truy vấn bạn đang chạy và phân tích những truy vấn nào đang mất nhiều thời gian để chạy bằng công cụ phân tích nhật ký truy vấn như pgFouine hoặc pqa. Xem " Truy vấn khó ghi nhật ký " để biết thêm thông tin.

Cách tiếp cận khác là xem xét pg_stat_user_tablesvà tìm kiếm các bảng có số lượng lớn các lần quét tuần tự chống lại chúng, ở đâu seq_tup_fetchlà lớn. idx_fetch_tupThay vào đó, khi một chỉ mục được sử dụng, số lượng được tăng lên. Điều đó có thể cho bạn biết khi một bảng không được lập chỉ mục đủ tốt để trả lời các truy vấn chống lại nó.

Trên thực tế, tìm ra những cột nào bạn nên lập chỉ mục sau đó? Điều đó thường dẫn trở lại nội dung phân tích nhật ký truy vấn một lần nữa.



1

PoWA có vẻ như là một công cụ thú vị cho PostgreSQL 9.4+. Nó thu thập số liệu thống kê, hình dung chúng và đề xuất các chỉ mục. Nó sử dụng pg_stat_statementsphần mở rộng.

PoWA là Trình phân tích khối lượng công việc PostgreSQL thu thập các số liệu thống kê về hiệu suất và cung cấp các biểu đồ và đồ thị theo thời gian thực để giúp theo dõi và điều chỉnh các máy chủ PostgreSQL của bạn. Nó tương tự như Oracle AWR hoặc 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 

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.