Я инициализирую таблицу с ~ 120M строками и несколькими столбцами (a,b,c,d
). После инициализации я хочу сопоставить эти столбцы с некоторыми предварительно вычисленными показателями, такими как a+b, (c+d)/a
et c.
Предположение о независимости: В действительности, метрики - это довольно дорогие выборки и объединения, которые не имеют значения для вопроса. Однако метрики полностью независимы (то есть они могут быть вычислены параллельно без какой-либо зависимости друг от друга). Вот почему я хотел бы найти способ убедить postgres выполнять UPDATE
параллельно.
ограничение только для чтения: После этой процедуры база данных не будет изменен любым способом, т. е. отныне будут выполняться только SELECT
запросы. Я упоминаю об этом, потому что, возможно, можно немного ослабить систему блокировки postgres.
Добавление дополнительных столбцов в настоящее время выполняется в два этапа следующим образом:
- Создание столбцов (последовательно):
ALTER TABLE tab ADD "x" ...;
ALTER TABLE tab ADD "y" ...;
...
Обновите столбцы с отдельными метриками. Я выполняю эти обновления параллельно (через сопрограммы или подпроцессы):
[query 1] UPDATE tab SET "x" = ...
[query 2] UPDATE tab SET "y" = ...
...
Блокировки: Даже если я могу выполнить те же самые запросы в их SELECT
версии только для чтения параллельно, я не могу выполнить UPDATE
s. Из того, что я прочитал, похоже, что postgres блокирует отдельные строки для обновления, что является неудачным для моего случая. Я либо получаю взаимоблокировки, либо запросы выполняются на одном ядре, и ускорение отсутствует (базовый уровень выполняет запросы последовательно).
Вопрос: как эффективно выполнять множество столбцов- мудрые независимые обновления параллельно? Я ищу ответ высокого уровня, а не фактический запрос. Какой подход я должен использовать?
Идеи Я рассмотрел, читая различные обсуждения:
- Найдите способ отключения построчной блокировки, а затем вычислите каждый новый столбец в отдельном запросе (параллельно). В качестве альтернативы, скажите postgres, что эти запросы могут выполняться параллельно.
- Вычислите все столбцы в одном запросе, однако разбейте все строки на дизъюнктивные множества. Затем выполните параллельное обновление этих нескольких столбцов для отдельных групп строк.
- Создайте новую таблицу для каждого столбца, вычислите показатели в отдельных запросах (сохраните результаты в новых таблицах). Затем обновите итоговую таблицу сразу из новых таблиц.
Спасибо!
EDIT 1 : один из запросов - прямое заполнение значений NULL , Другой в основном (a-b)/c
, однако, более сложный может выглядеть следующим образом (пришлось переименовать таблицы и столбцы):
CREATE TEMPORARY TABLE tmp_speak AS ( -- faster than subselect below
SELECT created
FROM FTable
WHERE event = 'speak'
);
WITH FDiff AS (
SELECT r.id AS id,
(
SELECT f.t
FROM tmp_speak AS f
WHERE r.created <= f.t
ORDER by f.t ASC
LIMIT 1
) - r.created as next_speak
FROM RTable as r
ORDER BY r.id
)
UPDATE RTable
SET next_speak = FDiff.next_speak
FROM FDiff
WHERE RTable.id = FTable.id