zubkov-andrei / pg_profile

Postgres historic workload reports
Other
212 stars 31 forks source link

Долго работает profile.take_sample #88

Closed AlexKir closed 4 months ago

AlexKir commented 4 months ago

Здравствуйте,

Очень долго работает profile.take_sample, не отрабатывает за 3 часа. После создания очередной порции таблиц/партиции не дождался выполнения. Запускал SELECT profile.take_sample(1,true);

PostgreSQL 15.4 (Debian 15.4-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit pg_profile 4.4

Можно ли как-то исключить сбор статистики по объектам или может по одной из БД в кластере?

Долго идет запрос

SELECT
 st.relid,st.indexrelid,st.schemaname,st.relname,st.indexrelname,st.idx_scan,NULL AS last_idx_scan,st.idx_tup_read,st.idx_tup_fetch,stio.idx_blks_read,stio.idx_blks_hit,NULL relsize,0,
 pg_class.reltablespace as tablespaceid,(ix.indisunique OR con.conindid IS NOT NULL) AS indisunique,pg_class.relpages::bigint * current_setting('block_size')::bigint AS relpages_bytes,
 0 AS relpages_bytes_diff
FROM
 pg_catalog.pg_stat_all_indexes st
  JOIN pg_catalog.pg_statio_all_indexes stio USING (relid, indexrelid, schemaname, relname, indexrelname)
  JOIN pg_catalog.pg_index ix ON (ix.indexrelid = st.indexrelid)
  JOIN pg_catalog.pg_class ON (pg_class.oid = st.indexrelid)
  LEFT OUTER JOIN pg_catalog.pg_constraint con ON (con.conindid = ix.indexrelid AND con.contype in ('p','u')) ;

Используется timescale. В pg_index более 800 000 строк. В pg_class более 2 000 000 строк. Разработчики так видят :(

План запроса вроде как такой же как и в других базах.

+------------------------------------------------------------------------------------------------------------------------------------------------------+
|                                                                      QUERY PLAN                                                                      |
+------------------------------------------------------------------------------------------------------------------------------------------------------+
| Nested Loop Left Join  (cost=29456.09..114849.71 rows=1 width=325)                                                                                   |
|   Join Filter: (con.conindid = ix.indexrelid)                                                                                                        |
|   ->  Nested Loop  (cost=28456.09..53119.76 rows=1 width=217)                                                                                        |
|         ->  Nested Loop  (cost=28455.66..53119.28 rows=1 width=217)                                                                                  |
|               ->  Nested Loop  (cost=28455.23..53118.83 rows=1 width=212)                                                                            |
|                     ->  Nested Loop  (cost=28454.80..53118.34 rows=1 width=208)                                                                      |
|                           ->  Gather  (cost=28454.37..53117.81 rows=1 width=140)                                                                     |
|                                 Workers Planned: 3                                                                                                   |
|                                 ->  Nested Loop  (cost=27454.37..52117.71 rows=1 width=140)                                                          |
|                                       Join Filter: (n.nspname = n_1.nspname)                                                                         |
|                                       ->  Nested Loop  (cost=27454.24..52117.55 rows=1 width=144)                                                    |
|                                             ->  Nested Loop  (cost=27453.81..52117.03 rows=1 width=148)                                              |
|                                                   ->  Nested Loop  (cost=27453.68..52116.88 rows=1 width=88)                                         |
|                                                         ->  Parallel Hash Join  (cost=27453.25..52116.35 rows=1 width=16)                            |
|                                                               Hash Cond: ((x.indrelid = x_1.indrelid) AND (x.indexrelid = x_1.indexrelid))           |
|                                                               ->  Parallel Seq Scan on pg_index x  (cost=0.00..23160.70 rows=286170 width=8)         |
|                                                               ->  Parallel Hash  (cost=23160.70..23160.70 rows=286170 width=8)                       |
|                                                                     ->  Parallel Seq Scan on pg_index x_1  (cost=0.00..23160.70 rows=286170 width=8) |
|                                                         ->  Index Scan using pg_class_oid_index on pg_class c  (cost=0.43..0.53 rows=1 width=72)     |
|                                                               Index Cond: (oid = x.indrelid)                                                         |
|                                                               Filter: (relkind = ANY ('{r,t,m}'::"char"[]))                                          |
|                                                   ->  Index Scan using pg_namespace_oid_index on pg_namespace n  (cost=0.13..0.15 rows=1 width=68)   |
|                                                         Index Cond: (oid = c.relnamespace)                                                           |
|                                             ->  Index Scan using pg_class_oid_index on pg_class c_1  (cost=0.43..0.51 rows=1 width=72)               |
|                                                   Index Cond: (oid = c.oid)                                                                          |
|                                                   Filter: ((c.relname = relname) AND (relkind = ANY ('{r,t,m}'::"char"[])))                          |
|                                       ->  Index Scan using pg_namespace_oid_index on pg_namespace n_1  (cost=0.13..0.15 rows=1 width=68)             |
|                                             Index Cond: (oid = c_1.relnamespace)                                                                     |
|                           ->  Index Scan using pg_class_oid_index on pg_class i  (cost=0.43..0.53 rows=1 width=68)                                   |
|                                 Index Cond: (oid = x.indexrelid)                                                                                     |
|                     ->  Index Scan using pg_class_oid_index on pg_class i_1  (cost=0.43..0.48 rows=1 width=68)                                       |
|                           Index Cond: (oid = i.oid)                                                                                                  |
|                           Filter: (i.relname = relname)                                                                                              |
|               ->  Index Scan using pg_index_indexrelid_index on pg_index ix  (cost=0.42..0.45 rows=1 width=5)                                        |
|                     Index Cond: (indexrelid = i.oid)                                                                                                 |
|         ->  Index Scan using pg_class_oid_index on pg_class  (cost=0.43..0.48 rows=1 width=12)                                                       |
|               Index Cond: (oid = i.oid)                                                                                                              |
|   ->  Gather  (cost=1000.00..61727.96 rows=157 width=4)                                                                                              |
|         Workers Planned: 4                                                                                                                           |
|         ->  Parallel Seq Scan on pg_constraint con  (cost=0.00..60712.26 rows=39 width=4)                                                            |
|               Filter: (contype = ANY ('{p,u}'::"char"[]))                                                                                            |
| JIT:                                                                                                                                                 |
|   Functions: 59                                                                                                                                      |
|   Options: Inlining false, Optimization false, Expressions true, Deforming true                                                                      |
+------------------------------------------------------------------------------------------------------------------------------------------------------+
(44 rows)
zubkov-andrei commented 4 months ago

Добрый день!

Выключить сбор статистик по объектам схем пока нельзя, а вот исключить некоторые базы данных из снимков можно. Для этого используйте функцию set_server_db_exclude(), описанную в разделе Managing servers.

Однако, я предлагаю вам начать с отключения JIT оптимизации в сессии, выполняющей снимок профайла (судя по вашему плану, она у вас включена). Сложно сказать насколько сильно она может влиять, но эффект может быть значительным.

AlexKir commented 4 months ago

Отключение jit не помогло. Исключил БД через set_server_db_exclude (вроде доку читал, но не увидел что так можно)

Спасибо !!!