我正在使用postgreSQL 7.4。
我有一张大桌子,称之为table_a:
key1 INT NOT NULL,
key2 INT NOT NULL,
data INT NOT NULL,
itstamp INT NOT NULL DEFAULT (date_part('EPOCH'::text, (timeofday())::timestamp without time zone))::INTEGER
和一个汇总key1最后更新时间的表,称之为table_b:
key1 INT NOT NULL,
max_itstamp INT NOT NULL
我在plpgsql中创建了一个触发器函数,以根据需要更新或插入table_b中的行:
CREATE OR REPLACE FUNCTION table_b_update() RETURNS TRIGGER AS '
DECLARE
l_key1 INT;
l_itstamp INT;
BEGIN
l_key1 := new.key1;
l_itstamp := new.itstamp;
PERFORM TRUE FROM table_b WHERE key1=l_key1;
IF NOT FOUND THEN
INSERT INTO table_b(key1, max_itstamp) values (l_key1, l_itstamp);
ELSE
UPDATE table_b SET max_itstamp=l_itstamp WHERE key1=l_key1;
END IF;
RETURN NULL;
END'
LANGUAGE plpgsql IMMUTABLE;
然后我将一个触发器附加到table_a:
CREATE TRIGGER table_a_trigger1 AFTER INSERT OR UPDATE ON table_a FOR EACH ROW
EXECUTE PROCEDURE table_b_upate();
现在,将新数据插入table_a的时间逐渐增加。 table_b的文件占用空间稳步增长。
我在函数中使用了RAISE NOTICE命令来确认If语句在第一次调用每个键后导致UPDATE而不是INSERT。
由于每个INSERT的插入时间都在增长,我在table_b上尝试了一个VACUUM FULL。插入时间更改回早期插入的大致时间。 table_b的文件大小大大减少了。在VACUUM FULL之后,插入时间开始再次增长。我不想在每次INSERT后都执行VACUUM FULL。
UPDATE是否可能在table_b中实际执行DELETE和INSERT?
答案 0 :(得分:1)
由于它的并发性哲学,Postgresql很少有UPDATE
到位,而且最近才有。{1}}。你的古董版确实在幕后做了DELETE/INSERT
对。
VACUUM
和CLUSTER
是经过批准的方法,可以保持表格大小的可管理性。 CLUSTER
锁定表(至少,它在7.3中)。您可能希望在非工作时间内经常运行普通VACUUM
(每天多次)和CLUSTER
。当然,这些频率取决于您的更新频率。
我对Postgresql的体验是向上迁移很容易; dump / restore每次都是第一次工作。
答案 1 :(得分:0)
7.4非常古老。你真的需要升级到一个具有良好autovacuum的最新版本,并将自动处理。
请勿使用VACUUM FULL(请尝试使用CLUSTER)。