Plpgsql, кажется, удаляет и вставляет вместо обновления - Почему? - PullRequest
1 голос
/ 17 мая 2011

Я использую 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?

Ответы [ 2 ]

1 голос
/ 18 мая 2011

Из-за своей философии параллелизма Postgresql редко делает UPDATE на месте, и это только недавно.Ваша античная версия действительно делает пару DELETE/INSERT за кулисами.

VACUUM и CLUSTER - это одобренные способы обеспечения управляемости размера таблицы.CLUSTER блокирует таблицу (по крайней мере, в 7.3).Вы, вероятно, хотите запускать обычные VACUUM часто (несколько раз в день) и CLUSTER в нерабочее время.Конечно, эти частоты зависят от частоты вашего обновления.

Мой опыт работы с Postgresql заключается в том, что миграция вверх легка;дамп / восстановление работали каждый раз впервые.

0 голосов
/ 17 мая 2011

7,4 очень старый.Вам действительно нужно перейти на последнюю версию, которая имеет хороший автовакуум и справится с этим автоматически.

Не используйте VACUUM FULL (попробуйте вместо этого CLUSTER).

...