我有一个将记录插入表中的过程。
该表是用这样的触发器定义的......
CREATE TRIGGER myTrig AFTER INSERT ON myTable FOR EACH ROW EXECUTE PROCEDURE myProcedure();
进入 myTable的过程不在INSERT
我的控制范围内,它基本上只是全天 24/7 将记录喷到表中。
中的功能myProcedure()
需要数据库资源。在繁忙时期,记录到达的速率大于数据库可以处理的速度(大约每秒 500 条记录是极限)。如果我使用禁用触发器,ALTER TABLE myTable DISABLE TRIGGER myTrig
那么系统每秒可以处理 1000 条记录。
然后我可以在系统不那么忙时重新启用触发器,但显然那些在禁用触发器时添加的记录将不会得到正确处理。
有什么方法可以在表中已经选定的记录上重新运行触发器吗?
我目前最好的猜测是,在繁忙时期,我应该将传入的记录转移到与myTable
原始记录相同的副本(但没有触发器),然后当系统稍后安静下来时,我可以从副本插入,回到原来的位置应该由触发器处理(尽管晚于它们应该处理的时间)
触发函数需要触发操作。触发时,
FOR EACH ROW
它通常还需要触发行作为输入。但是一个简单的函数几乎可以重放触发器函数所做的任何事情。最好的做法取决于触发函数是否
myProcedure()
改变了插入的行本身。如果是这样,那么您使用单独的临时表的想法听起来不错。以后
UPDATE
无论如何都会写一个新的行版本。因此,首先写入暂存表然后INSERT
再写入目标表总体上是高效的。如果在服务器崩溃的情况下丢失数据是可以接受的,您甚至可以UNLOGGED
为此使用一个表,并且每秒处理更多的行。最终
INSERT
到主表也会触发触发器,一切都完成了。如果不是(如果
UNLOGGED
表不是一个选项),我会直接写到目标表。触发器函数所做的一切现在都可以用普通函数重播。如果您不能复制触发器函数的功能,下一个最佳想法是写入 的副本myTable
,上面有相同的触发器。只做它RETURN NULL;
而不是RETURN NEW;
跳过触发行本身。(因此没有任何内容写入副本。)如果您不能或不会修改触发器函数的副本,或者像这样在临时表上添加另一个触发器:
这也会跳过触发插入本身。
myProcedure()
但是从较早的触发器中执行的所有内容仍然存在。手册: