У меня есть таблица, которая выглядит следующим образом:
CREATE TABLE tmp (
id uuid primary key,
other_id uuid,
...
);
В этой таблице миллионы записей, и мне нужно: просмотреть их все, проверить и сравнить значения некоторых из ее полей сзначения другой таблицы и исправьте значения.
Я не хотел использовать стандартный подход ORDER BY ... LIMIT ... OFFSET ...
, поскольку его производительность сильно страдает для больших смещений. Поэтому я попытался использовать подход «поиск по индексу», пример здесь .
Моя проблема в том, что я получаю ошибки по одному, и я не уверен (концептуально)как решить это в коде PL / pgSQL. Примерно так:
-- Get initial offset
SELECT id INTO _id_offset
FROM tmp
WHERE ...
ORDER BY id DESC
LIMIT 1
WHILE ... LOOP -- Loop until some fixed high value to prevent infinite loop, just in case
SELECT id, other_id, ... INTO rows_to_update
FROM tmp
WHERE id < _id_offset AND (...) -- Latter part is same condition as above
ORDER BY id DESC
FETCH NEXT _batch_size ROWS ONLY
-- Get next offset
SELECT id INTO _id_offset
FROM rows_to_update
ORDER BY id ASC -- ASC to get the "last" id from above. Cannot simply use _batch_size offset as there may be fewer entries left.
LIMIT 1
-- Update relevant records, check # of updated records to see
-- if we can terminate loop early, update loop condition
...
END LOOP;
Неудивительно, что первая и последняя запись пропускаются из-за условия <
. Было бы довольно просто исправить это поведение в коде приложения, но я не уверен, как это должно выглядеть в PL / pgSQL.
Есть ли более простой способ перебрать всю таблицу в эффективномкак использовать PL / pgSQL?