Я использую 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 после первого вызова для каждого ключа.
Так как время вставки увеличивается для каждой вставки, я попытался VACUUM FULL на table_b. Время вставки изменилось обратно на приблизительное время ранних вставок. Размер файла для table_b был значительно уменьшен. После того, как ВАКУУМ ПОЛНЫЙ, время вставки снова начало расти. Я не хочу делать VACUUM FULL после каждой вставки.
Возможно ли, что UPDATE действительно выполняет DELETE и INSERT в table_b?