1

Мой сценарий:Postgresql параллельно насыпной ВСТАВИТЬ с работником не распараллеливание

  • 10 работник
  • Database установил 100 макс соединений
  • Каждый работник имеет свой собственный DB соединения (не более 10 соединений.)
  • Каждый рабочий начинает транзакцию (BEGIN; COMMIT;)
  • Каждый работник вставляет данные в одну и ту же таблицу с объемной вставкой внутри транзакции
  • Данные для вставки, например. 1 миллион строк
  • Каждый рабочий обрабатывает 1000 строк (партии размером 1000)

запроса каждого рабочего:

BEGIN; 
    INSERT INTO "test_tbl" ("id",...) VALUES 
    (...),(...),...[1000 entries]... RETURNING id; 
COMMIT; 

Таблица test_tbl имеет единственное ограничение PRIMARY KEY (id) с индексом CREATE UNIQUE INDEX formulas_pkey ON formulas USING btree (id)

Задача

После многочасового анализа выясняется, что рабочий ожидает, что другой рабочий закончит вставку. Почему рабочие не могут вставлять новые данные в одну и ту же таблицу одновременно?

UPDATE

Я снял все ограничения и все индексы (первичные ключи, внешние ключи и т.д.), но по-прежнему та же проблема. Нет распараллеливания.

Добавлено примечание:

  • данных для вставки, например, 1 миллион строк
  • Каждый работник обрабатывает 1000 строк (партии размером 1000)
+0

Аналогичный [вопрос SO] (http://stackoverflow.com/q/32087233/1835769). – displayName

ответ

1

Тот факт, что первичный ключ означает, что база данных для проверки значений соответствующего столбца (ов), чтобы быть UNIQUE и NOT NULL. Вторая транзакция, начинающаяся с вставки данных, не может сделать ее до тех пор, пока первая не закончит вставку (в противном случае может быть не уникальными значениями).

Если вы просто не делаете объемную вставку в сделка на одного работника (но, допустим, партии из 100 вставок), она будет работать намного быстрее. Вам потребуется больше вызовов между клиентом и базой данных (у вас будет n звонки со 100 строками данных, а не очень большой звонок с n * 100 строк); но база данных сможет совершить гораздо раньше.

В PostgreSQL:

чтения никогда не блокирует письма и письма никогда не блокирует чтение

... но сделка 1 написание может (и часто) транзакционный блок 2 также написание ,

В случае, если вы не можете сделать пакетные вставки, вы можете попробовать откладываяPRIMARY KEY ограничения в конце transaction.This делается путем определения вашего PRIMARY KEY ограничения DEFERRABLE INITIALLY DEFERRED (который не является значение по умолчанию для PostgreSQL, хотя это SQL). Смотрите documentation for "create table":

DEFERRABLE
NOT DEFERRABLE

Это контролирует, может ли быть отложено ограничение. Ограничение, которое не откладывается, будет проверяться сразу после каждой команды. Проверка ограничений, которые откладываются, может быть отложена до конца транзакции (с помощью команды SET CONSTRAINTS). NOT DEFERRABLE - значение по умолчанию. В настоящее время только ограничения UNIQUE, PRIMARY KEY, EXCLUDE и REFERENCES (внешний ключ) принимают этот пункт.

+0

Thx @joanolo! Пожалуйста, прочтите мое обновление. – phlegx

+0

Что вы имеете в виду: «Если вы просто не делаете объемную вставку в 1 транзакцию на одного работника (но, допустим, партии из 100 вставок), она будет работать намного быстрее».? Мой рабочий делает пакетные вставки из 1000 записей в 1 транзакцию. – phlegx

+0

Это было непонятно в вашем оригинальном посте. Сделанные изменения теперь дают понять. – joanolo

Смежные вопросы