@BetsuNo
Программист

Как избавиться от блокировок уровня записи и повысить производительность больших таблиц в PostgreSQL?

Есть две ситуации:
  1. Таблица с ~20k записей, часть из которых часто (до нескольких раз в секунду) обновляется запросами вида "UPDATE table_1 SET counter = counter + 1 WHERE id = 123". При этом запись может заблокироваться на два часа, и все последующие запросы повиснут в воздухе до разблокировки.
  2. Таблица с ~2.5M записей, данные добавлются скопом (INSERT SELECT), и потом по одной строке удаляются. Здесь просто производительность ниже плинтуса.

Индексы по частоиспользуемым полям добавлены. Как с этими проблемами бороться? Я грешу на autovacuum, по крайней мере во втором случае, но толковых рекомендаций, как настраивать его, не нашел.
Окружение: сервер PostgreSQL 9.5 с 16ГБ оперативки, ssd диском и pgbouncer в качестве пул-менеджера.

Заранее спасибо.
  • Вопрос задан
  • 677 просмотров
Решения вопроса 1
@BetsuNo Автор вопроса
Программист
Как оказалось, первая проблема связана с особенностями работы pgbouncer. Суть в том, что pgbouncer не блокирует соединение, в котором есть активная транзакция, для других клиентов, а у нас в одном месте происходит довольно длительная (до 15 минут может висеть) транзакция на совершенно левой группе таблиц. В общем получалось так, что проходила куча update на одну строку из одной таблицы, и часть из них попадала в транзакцию, которая предназначалась для других таблиц, и потом, после комита, сервер еще долго разбирался, в каком порядке это все выполнять. Решение: оборачивать в отдельную транзакцию важные запросы на изменение данных (в нашем случае - обновление счетчика), даже если они ходят поодиночке.
А вторую проблему решили изменением структуры таблицы.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
begemot_sun
@begemot_sun
Программист в душе.
Как минимум не удалять, а помечать что удалено. Потом удалять скопом.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы