Postgres: Как обновить независимые столбцы параллельно? - PullRequest
0 голосов
/ 01 мая 2020

Я инициализирую таблицу с ~ 120M строками и несколькими столбцами (a,b,c,d). После инициализации я хочу сопоставить эти столбцы с некоторыми предварительно вычисленными показателями, такими как a+b, (c+d)/a et c.

Предположение о независимости: В действительности, метрики - это довольно дорогие выборки и объединения, которые не имеют значения для вопроса. Однако метрики полностью независимы (то есть они могут быть вычислены параллельно без какой-либо зависимости друг от друга). Вот почему я хотел бы найти способ убедить postgres выполнять UPDATE параллельно.

ограничение только для чтения: После этой процедуры база данных не будет изменен любым способом, т. е. отныне будут выполняться только SELECT запросы. Я упоминаю об этом, потому что, возможно, можно немного ослабить систему блокировки postgres.

Добавление дополнительных столбцов в настоящее время выполняется в два этапа следующим образом:

  1. Создание столбцов (последовательно):
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 блокирует отдельные строки для обновления, что является неудачным для моего случая. Я либо получаю взаимоблокировки, либо запросы выполняются на одном ядре, и ускорение отсутствует (базовый уровень выполняет запросы последовательно).

Вопрос: как эффективно выполнять множество столбцов- мудрые независимые обновления параллельно? Я ищу ответ высокого уровня, а не фактический запрос. Какой подход я должен использовать?

Идеи Я рассмотрел, читая различные обсуждения:

  1. Найдите способ отключения построчной блокировки, а затем вычислите каждый новый столбец в отдельном запросе (параллельно). В качестве альтернативы, скажите postgres, что эти запросы могут выполняться параллельно.
  2. Вычислите все столбцы в одном запросе, однако разбейте все строки на дизъюнктивные множества. Затем выполните параллельное обновление этих нескольких столбцов для отдельных групп строк.
  3. Создайте новую таблицу для каждого столбца, вычислите показатели в отдельных запросах (сохраните результаты в новых таблицах). Затем обновите итоговую таблицу сразу из новых таблиц.

Спасибо!

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...