как ускорить update?

pgdumper
Дата: 27.05.2004 10:00:16
есть вот такой update
update quotas set qt_traf_cur=qt_traf_cur-1 where pk_qt=144
вот примерный план его выполнения

Index Scan using quotas_pkey on quotas (cost=0.00..110.00 rows=1 width=133)
(actual time=0.37..143.61 rows=1 loops=1)
Index Cond: (pk_qt = 144)
Total runtime: 314.86 msec
(3 rows)

беда в том, что total runtime имеет свойство увеличиваться до 7-8 секунд!
update очень интенсивный.
есть рецепны как уменьшить время выполнения?
Hordi
Дата: 27.05.2004 11:58:28
В твоем случае архитектурно все идеально (индекс в запрос включен). Поэтому единственное что возможно, это регулярно делать VACUUM FULL ANALYZE.
LeXa NalBat
Дата: 27.05.2004 12:03:21
Может быть изменить приложение, вместо сотни апдейтов "set qt_traf_cur=qt_traf_cur-1" выполнять один "set qt_traf_cur=qt_traf_cur-100"?
pgdumper
Дата: 27.05.2004 13:26:15
to LeXa NalBat

дело в том, что в реальности выражение выглядит как

"update quotas set qt_traf_cur=qt_traf_cur-? where pk_qt=?",

и только в момент выполнения ? заменяются на реальные величины.
кэширование в приложении реализовано.

to Hordi

"регулярно" это насколько часто? у меня крон скрипт раз в сутки (ночью) запускается. нужно чаще? как выполнение этой операции в разгар рабочего дня повлияет на реактивность субд?
pgdumper
Дата: 27.05.2004 14:54:36
нашел ответы здесь. спасибо Genady
Wireless
Дата: 28.05.2004 15:01:16
Если к твоей таблице quotas происходит огромное число
параллельных обращений, то может помочь техника
замены UPDATE на INSERT. Естественно, это потребует
переписание всех остальных запросов к этой таблице.

Рассмотрим на другом примере - система счетчиков обращений к сайтам
(число посещений/просмотров, хостов по каждому сайту).
Напр, запрос
UPDATE sitestat SET visits = visits + 1 WHERE site_id = $site_id

заменить на
INSERT INTO sitestat_v2 (site_id, visits) VALUES ($site_id, 1)

Соотв-но, запрос получения стат-ки по какому-либо сайту
будет выглядеть как SELECT SUM(visits) FROM sitestat_v2 WHERE site_id=$site_id .
Поверьте, на очень волатильных таблицах таблицах этот запрос
будет выполняться практически столько же, сколько и
SELECT visits FROM sitestat WHERE ...
так как UPDATE в PostgreSQL - суть тот же INSERT, только еще плюс
неявный DELETE (вспоминайте про MVCC...).

Но, повторяю, экономия будет только если мы имеем большое число
параллельных обращений к таблице. Производительность повышается
за счет уменьшения числа ожиданий/локировок.

Естественно, ночью или в другое время, когда нагрузка снижается
при этой технике нужно запускать скрипт, который бы агрегировал
статистику по каждому сайту. В результате на каждый сайт останется
по 1 записи. После этого скрипта запускай VACUUM [FULL].

Удачи.