【发布时间】:2020-09-29 08:05:36
【问题描述】:
我在 Postgres 12 上重复运行存储过程,每次运行不同的日期。最初,存储过程需要 3 到 10 秒才能运行,但在连续运行多次后,大约一个小时,存储过程开始需要更长的时间(大约 1 分钟或更长时间)。
存储过程中使用的表的简单查询也开始需要比平时更长的时间来运行。在此表上运行 VACCUUM ANALYZE 后,查询再次加速。
我想知道导致查询开始运行如此缓慢的问题可能出在哪里。
我已经对来自部分存储过程的简单查询运行了解释(分析,缓冲区)并将其保存在以下链接中,也很高兴分享完整存储过程的解释(分析,缓冲区)。
在存储过程快速时解释(Analyse, Buffer):https://explain.depesz.com/s/yrse
在存储过程慢时解释(Analyse, Buffer):https://explain.depesz.com/s/uQel
产生解释(分析,缓冲区)的代码
SELECT period_id, classification_id,dtz,now() as create_dt,now() as update_dt,
false as latest_record,ratio_1
FROM zpart.ratios_y2020 r
where classification_id is not null and universe_weight is not null
and dtz='2020-03-28 00:00'::timestamptz
以下是特定日期的存储过程代码。
create temp table t_rr as
with cte as (
SELECT period_id, classification_id,dtz,now() as create_dt
,now() as update_dt,false as latest_record,ratio_1
FROM zpart.ratios_y2020 r
where classification_id is not null and universe_weight is not null
and dtz='2020-03-28 00:00'::timestamptz
)
SELECT period_id, classification_id,dtz,now() as create_dt,now() as update_dt,false as latest_record
, percentile_cont(array(SELECT generate_series(0, 99) :: NUMERIC / 100)) WITHIN GROUP
(ORDER BY ratio_1) AS lower_bounds_1
FROM cte r
GROUP BY period_id, classification_id, dtz
union all
SELECT period_id, 1 as classification_id,dtz,now(),now(),false
,percentile_cont(array(SELECT generate_series(0, 99) :: NUMERIC / 100)) WITHIN GROUP
(ORDER BY ratio_1) AS lower_bounds_1
FROM cte r
GROUP BY period_id, dtz
union all
SELECT period_id, 2 as classification_id,dtz,now(),now(),false
,percentile_cont(array(SELECT generate_series(0, 99) :: NUMERIC / 100)) WITHIN GROUP
(ORDER BY ratio_1) AS lower_bounds_1
FROM cte r
where classification_id!=3
GROUP BY period_id, dtz;
insert into zpart.rank_ranges_y2020(period_id, classification_id, dtz, create_dt, update_dt,
latest_record, lower_bounds_1)
SELECT period_id, classification_id, dtz, create_dt, update_dt, latest_record,lower_bounds_1
FROM t_rr r
on conflict (dtz,period_id,classification_id) do update set update_dt=now(),
latest_record=EXCLUDED.latest_record,lower_bounds_1=EXCLUDED.lower_bounds_1;
truncate t_rr; drop table if exists t_rr;
编辑 问题是由 ReadIOP 超出其分配引起的,随着时间的推移导致数据库变慢。
【问题讨论】:
-
索引的定义是什么?
-
请为这些查询显示
EXPLAIN (ANALYZE, BUFFERS),最好在打开track_io_timing之后显示 -
我更新了帖子中的链接以显示
EXPLAIN (ANALYZE, BUFFERS)的输出。表上的索引在 (security_id, period_id, dtz) 上定义为唯一的。该表还按 period_id 分区,这就是为什么您会在解释分析中看到诸如 ratiosy2020p9 之类的表名。有 7 个不同的 period_id(1、9、11、12、14、15、17)。 -
您是否让交易保持打开状态?
标签: postgresql stored-procedures