Czy istnieje narzędzie lub metoda do analizy Postgres i określenia, które brakujące indeksy należy utworzyć, a które nieużywane indeksy usunąć? Mam niewielkie doświadczenie w robieniu tego z narzędziem „profiler” dla SQLServer, ale nie znam podobnego narzędzia dołączonego do Postgres.
sql
database-design
postgresql
Cerin
źródło
źródło
Odpowiedzi:
Lubię to, aby znaleźć brakujące indeksy:
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;
Sprawdza, czy jest więcej skanowań sekwencji niż indeksów. Jeśli tabela jest mała, jest ignorowana, ponieważ Postgres wydaje się preferować skanowanie sekwencyjne.
Powyższe zapytanie ujawnia brakujące indeksy.
Następnym krokiem byłoby wykrycie brakujących indeksów połączonych. Myślę, że nie jest to łatwe, ale wykonalne. Może analiza wolnych zapytań ... Słyszałem, że pg_stat_statements może pomóc ...
źródło
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;
too_much_seq
jest pozytywne i duże, powinieneś się martwić.::regclass
nie będzie działać z identyfikatorami wielkimi literami, @Mr. Piżmak ma dobre rozwiązanie, można go również użyć('"' || relname || '"')::regclass
zamiast niego.Sprawdź statystyki.
pg_stat_user_tables
ipg_stat_user_indexes
od których należy zacząć.Zobacz „ Kolektor statystyk ”.
źródło
Podejście do określenia brakujących indeksów ... Nie. Ale są pewne plany, aby ułatwić to w przyszłym wydaniu, takie jak pseudoindeksy i czytelne maszynowo EXPLAIN.
Obecnie musisz
EXPLAIN ANALYZE
wykonywać zapytania o niskiej wydajności, a następnie ręcznie określić najlepszą trasę. Niektóre analizatory dzienników, takie jak pgFouine, mogą pomóc w określeniu zapytań.Jeśli chodzi o nieużywany indeks, możesz użyć czegoś takiego jak poniżej, aby je zidentyfikować:
select * from pg_stat_all_indexes where schemaname <> 'pg_catalog';
Pomoże to zidentyfikować przeczytane, zeskanowane, pobrane krotki.
źródło
Kolejnym nowym i interesującym narzędziem do analizy PostgreSQL jest PgHero . Bardziej koncentruje się na dostrajaniu bazy danych i przedstawia liczne analizy i sugestie.
źródło
Możesz użyć poniższego zapytania, aby znaleźć użycie indeksu i rozmiar indeksu:
Odniesienie pochodzi z tego bloga.
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;
źródło
Istnieje wiele linków do skryptów, które pomogą Ci znaleźć nieużywane indeksy na wiki PostgreSQL . Podstawową techniką jest przyjrzenie się
pg_stat_user_indexes
i wyszukanie tychidx_scan
, w których liczba, ile razy ten indeks został użyty do udzielenia odpowiedzi na zapytania, wynosi zero lub przynajmniej jest bardzo niska. Jeśli aplikacja uległa zmianie, a poprzednio używany indeks prawdopodobnie nie jest teraz, czasami trzeba uruchomićpg_stat_reset()
wszystkie statystyki z powrotem do 0, a następnie zebrać nowe dane; możesz zapisać aktualne wartości wszystkiego i zamiast tego obliczyć różnicę, aby to rozgryźć.Nie ma jeszcze żadnych dobrych narzędzi sugerujących brakujące indeksy. Jedną z metod jest rejestrowanie zapytań, które uruchamiasz i analizowanie, które z nich zajmują dużo czasu, za pomocą narzędzia do analizy dziennika zapytań, takiego jak pgFouine lub pqa. Aby uzyskać więcej informacji, zobacz „ Rejestrowanie trudnych zapytań ”.
Innym podejściem jest przyjrzenie się
pg_stat_user_tables
i wyszukanie tabel, które mają dużą liczbę sekwencyjnych skanów, gdzieseq_tup_fetch
jest duża. Gdy używany jest indeks,idx_fetch_tup
zamiast tego liczba jest zwiększana. Może to wskazać, kiedy tabela nie jest indeksowana wystarczająco dobrze, aby odpowiadać na zapytania.Właściwie zastanawiasz się, które kolumny należy następnie indeksować? Zwykle prowadzi to z powrotem do analizy dziennika zapytań.
źródło
Można go znaleźć za pomocą następującego zapytania w konsoli postgres
use db_name select * from pg_stat_user_indexes; select * from pg_statio_user_indexes;
Aby uzyskać więcej informacji, https://www.postgresql.org/docs/current/monitoring-stats.html
źródło
PoWA wydaje się być interesującym narzędziem dla PostgreSQL 9.4+. Zbiera statystyki, wizualizuje je i proponuje indeksy. Używa
pg_stat_statements
rozszerzenia.źródło
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
źródło
To powinno pomóc: Praktyczna analiza zapytań
źródło