我每小时和每天都有2张桌子,我的目标是计算每小时表格的平均值并将其保存到每日表格中。我写了一个像这样的触发函数 -
CREATE OR REPLACE FUNCTION public.calculate_daily_avg()
RETURNS trigger AS
$BODY$
DECLARE chrly CURSOR for
SELECT device, date(datum) datum, avg(cpu_util) cpu_util
FROM chourly WHERE date(datum) = current_date group by device, date(datum);
BEGIN
FOR chrly_rec IN chrly
LOOP
insert into cdaily (device, datum, cpu_util)
values (chrly_rec.device, chrly_rec.datum, chrly_rec.cpu_util)
on conflict (device, datum) do update set
device=chrly_rec.device, datum=chrly_rec.datum, cpu_util=chrly_rec.cpu_util;
return NEW;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE NOTICE 'NO DATA IN chourly FOR %', current_date;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION public.calculate_daily_avg()
OWNER TO postgres;
和小时表上的触发器 -
CREATE TRIGGER calculate_daily_avg_trg
BEFORE INSERT OR UPDATE
ON public.chourly
FOR EACH ROW
EXECUTE PROCEDURE public.calculate_daily_avg();
但是当我尝试在每小时表中插入或更新大约3000条记录时,只插入了3或4个设备,而不是3000.(同样在触发器中我已经尝试过AFTER INSERT或UPDATE,但即使这样也会产生相同的结果)我在这里做错了?如果你觉得我写错了,请建议任何更好的方法来编写触发器。谢谢!
答案 0 :(得分:0)
我不建议在TRIGGER
时使用INSERT
进行计算。尝试使用cron每小时或每天执行函数的不同方法。
为什么?
因为每次INSERT
一行。 postgres将始终为插入(基于您的流程)执行聚合函数AVG()
和LOOPING
。
这意味着另一个INSERT
语句将等待Previous INSERT
提交,这将使您的数据库性能受到高度INSERT Transaction
的影响。如果您以某种方式管理BREAK
规则(可能来自配置),您将获得inconsistent
数据,就像您现在发生的事情一样。