Мой сервис получает пакеты из нескольких тысяч необработанных записей, каждая из которых содержит имя.Ожидается, что многие записи будут иметь одно и то же имя, поэтому стратегия дедупликации была настроена следующим образом.
Таблица records
содержит в основном все данные из каждой необработанной записи, кроме имени, которое заменяется идентификатором.указывая на глобальную таблицу names
, где столбец name
уникален.
Я использую следующий запрос для ETL.Для каждой партии из 5 тыс. Записей я создаю одну транзакцию с 5 тыс. Операторов после этого запроса:
WITH new_id AS (
INSERT INTO names
VALUES (
DEFAULT,
@raw_name
)
ON CONFLICT (name)
DO UPDATE
SET id = (
SELECT id FROM names WHERE name = @raw_name
)
RETURNING id
)
INSERT INTO records VALUES (
DEFAULT,
(SELECT id FROM new_id),
-- other (constant) stuff
);
Цель здесь - вставить имя в таблицу names
, если оно еще не существует.В обоих случаях идентификатор имени извлекается и прикрепляется к записи, которая вставляется в таблицу records
.
Выполнение транзакции занимает около 2,5 с для 5000 записей, и я ищу для оптимизации времени выполненияэтот запрос.Временное выделение памяти или таблицы допустимо.Я также могу влиять на размер партии (мин. 1 КБ).Я должен работать с существующей схемой (две таблицы).
(Мне также интересно, есть ли способ оптимизировать это с помощью параллелизма. Я могу запускать сразу несколько заданий ETL, но запрос в том виде, в каком он есть, немедленно заходит в тупик.)