********************************************************************************************* Например, с помощью вот такого запроса мы можем найти топ 5 таблиц, по которым чаще всего происходило последовательное сканирование: SELECT schemaname, relname, seq_scan, seq_tup_read, seq_tup_read / seq_scan as avg_seq_tup_read FROM pg_stat_all_tables WHERE seq_scan > 0 ORDER BY 5 DESC LIMIT 5; Зная, какие запросы выполняются к таким таблицам, можно вычислить неоптимальный запрос. Если предыдущие запросы не дали ни каких результатов и у вас все хорошо оптимизированно, то подсказу может дать колонка calls в представлении pg_stat_statements. Эта колонка покажет как часто вызывался запрос. Может случится так, что запрос вызывается слишком часто из-за каких-то сбоев в приложении или неоптимального кода, что приводит к сильной загрузке CPU ********************************************************************************************* Если мы хотим, чтобы наша база данных работала эффективно и производительно, то за ней нужно следить, выявлять неоптимальные запросы и различные аномалии. В этом нам и поможет представление pg_stat_all_tables. pg_stat_all_tables покажет нам статистику по всем таблицам базы данных (системным и пользовательским), покажет кол-во последовательных и индексных сканирований, операций по удалению, обновлению и вставки строк, а также кол-во "мертвых" строк и статус операций VACUUM и ANALYZE. Короче очень полезно представление 🤓 Давайте рассмотрим несколько полезных запросов к этому представлению. ✅ Смотрим количество операций последовательного сканирования пользовательских таблиц: SELECT schemaname, relname, seq_scan, idx_scan, seq_tup_read, seq_tup_read / seq_scan as avg_seq_read FROM pg_stat_all_tables WHERE seq_scan > 0 AND schemaname not in ('pg_catalog','information_schema','pg_toast') ORDER BY avg_seq_read DESC LIMIT 10; Этот запрос покажет топ 10 пользовательских таблиц, по которым было больше всего операций последовательного сканирования. ✅ Находим неиспользуемые или редко используемые таблицы: SELECT schemaname, relname, seq_scan, idx_scan, (COALESCE(seq_scan, 0) + COALESCE(idx_scan, 0)) as total_scans_performed FROM pg_stat_all_tables WHERE (COALESCE(seq_scan, 0) + COALESCE(idx_scan, 0)) < 10 AND schemaname not in ('pg_catalog', 'information_schema', 'pg_toast') ORDER BY 5 DESC; Запрос покажет таблицы, у которых операции последовательного и индексного сканирования не превышали кол-ва 10ть. ✅ Смотрим активность операций записи по пользовательским таблицам: SELECT st.schemaname,st.relname, pg_size_pretty(pg_total_relation_size(st.relid)) as Total_Size, st.seq_scan, st.idx_scan, st.n_tup_ins, st.n_tup_upd, st.n_tup_del FROM pg_stat_all_tables st WHERE st.schemaname not in ('pg_catalog','information_schema','pg_toast') ORDER BY Total_Size DESC; Запрос покажет кол-во операций последовательного и индексного сканирования по таблицам, а также кол-во операций вставки, удаления и обновления строк таблиц. ✅ Смотрим кол-во "живых" и "мертвых" строк пользовательских таблиц и проверяем статус VACUUM: SELECT schemaname, relname, n_live_tup, n_dead_tup, n_dead_tup * 100 / (case when n_live_tup > 0 then n_live_tup else 1 end) as dead_rows_percent, last_autovacuum, last_autoanalyze, n_dead_tup, relname FROM pg_stat_all_tables WHERE schemaname not in ('pg_catalog','information_schema','pg_toast') ORDER BY n_dead_tup DESC; Запрос покажет кол-во "мертвых" строк на таблицах, а также время последнего прихода AUTOVACUUM в таблицу. Как видите представление pg_stat_all_tables очень полезно для анализа статистики таблиц баз данных PostgreSQL. Конечно это не все возможные полезные запросы к этому представлению, в будущих постах будем публиковать и другие запросы, которые смогут на помочь в деле оптимизации производительности PostgreSQL 🧐