У меня очень большая таблица базы данных в PostgresQL и столбец типа «скопировано». Каждая новая строка начинается не скопированной и позже будет реплицирована на другую вещь с помощью фоновой программы. В этой таблице есть частичный индекс "btree (ID) WHERE replicated = 0". Фоновая программа выбирает не более 2000 записей (LIMIT 2000), обрабатывает их и затем фиксирует изменения в одной транзакции, используя 2000 подготовленных sql-команд.
Теперь проблема в том, что я хочу дать пользователю возможность сбросить это реплицированное значение, снова обнулить все.
Обновленный набор таблиц обновлений = 0;
невозможно:
- Это занимает очень много времени
- Он дублирует размер таблицы из-за MVCC
- Это делается за одну транзакцию: либо происходит сбой, либо проходит.
Мне на самом деле не нужны функции транзакций для этого случая: если система выйдет из строя, она будет обрабатывать только ее части.
Несколько других проблем:
Делать
update set replicated=0 where id >10000 and id<20000
также плохо: он выполняет последовательное сканирование всей таблицы, что слишком медленно.
Если бы он этого не делал, он все равно был бы медленным, потому что было бы слишком много поисков.
Что мне действительно нужно, так это способ пройти через все строки, изменить их и не быть привязанным к гигантской транзакции.
Странно, но
UPDATE table
SET replicated=0
WHERE ID in (SELECT id from table WHERE replicated= LIMIT 10000)
тоже медленно, хотя это должно быть хорошо: просмотрите таблицу в DISK-порядке ...
(Обратите внимание, что в этом случае был также индекс, который охватывал это)
(Обновление LIMIT, такое как Mysql, недоступно для PostgresQL)
Кстати: реальная проблема более сложна, и мы говорим о встроенной системе, которая уже развернута, поэтому удаленные изменения схемы трудны, но возможны
Это, к сожалению, PostgresQL 7.4.
Количество строк, о которых я говорю, например, 90000000. Размер базы данных может составлять несколько десятков гигабайт.
Сама база данных содержит только 5 таблиц, одна очень большая.
Но это неплохой дизайн, потому что эти встроенные блоки работают только с одним видом сущности, это не ERP-система или что-то в этом роде!
Есть идеи?