Postgresql postgres触发器函数仅在另一个表中插入少量记录
我每小时和每天有两个表,我的目标是计算每小时表的平均值,并将其保存到每日表。我已经写了一个这样的触发器函数-Postgresql postgres触发器函数仅在另一个表中插入少量记录,postgresql,triggers,Postgresql,Triggers,我每小时和每天有两个表,我的目标是计算每小时表的平均值,并将其保存到每日表。我已经写了一个这样的触发器函数- 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)
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条。(同样在触发器中,我在插入或更新后已经尝试过,但即使这样也会得到相同的结果)我在这里做错了什么?如果你觉得我写错了,请提出更好的方法来写触发器。谢谢 我不建议在
插入时使用触发器
进行计算。尝试不同的方法,使用cron每小时或每天执行的函数
为什么?
因为每次你插入一行。postgres将始终执行插入的聚合函数AVG()
和循环
(基于您的流)
这意味着另一个INSERT
语句将等待上一次INSERT
提交,这将影响数据库在高度INSERT事务中的性能。如果您设法打破规则(可能来自配置),您将得到不一致的数据,比如您现在发生的事情。我不建议在插入时使用触发器
进行计算。尝试不同的方法,使用cron每小时或每天执行的函数
为什么?
因为每次你插入一行。postgres将始终执行插入的聚合函数AVG()
和循环
(基于您的流)
这意味着另一个INSERT
语句将等待上一次INSERT
提交,这将影响数据库在高度INSERT事务中的性能。如果你设法打破了规则(可能来自配置),你会得到不一致的数据,比如你现在发生的事情。谢谢你解释得很好Adrian。如果我需要坚持使用触发器,那么我是否可以通过添加睡眠来等待触发器中的所有插入?尽管如此,Cron方法似乎是更好的选择。@dappler不,您不能通过添加睡眠,因为您不知道确切的查询执行时间。如果你在高流量的情况下睡眠(比如说20秒)。但当低流量时,插入也会等待20秒。我们不希望这种情况发生。cron方法比牺牲事务性能和潜在死锁要好得多。我将触发器函数替换为just函数,并从java调用它。谢谢谢谢你的解释,阿德里安。如果我需要坚持使用触发器,那么我是否可以通过添加睡眠来等待触发器中的所有插入?尽管如此,Cron方法似乎是更好的选择。@dappler不,您不能通过添加睡眠,因为您不知道确切的查询执行时间。如果你在高流量的情况下睡眠(比如说20秒)。但当低流量时,插入也会等待20秒。我们不希望这种情况发生。cron方法比牺牲事务性能和潜在死锁要好得多。我将触发器函数替换为just函数,并从java调用它。谢谢