Проблема с пропускной способностью PostgreSQL DELETE / INSERT

У меня проблема с пропускной способностью последовательностей УДАЛЕНИЕ / ВСТАВКА в PostgreSQL 9.0. Ищу идеи по улучшению ситуации.

На доступном нам оборудовании я могу ВСТАВЛЯТЬ новые строки в базу данных с постоянной скоростью 3000 / с (равномерно по 10 таблицам), значительно превышая 1 миллион строк в каждой таблице, которую я обычно тестирую. Однако, если я переключаюсь в режим, в котором мы УДАЛЯЕМ строку и повторно ВСТАВЛЯЮ ее с другими данными, производительность упадет более чем на порядок до 250 строк / с (опять же, равномерно по 10 таблицам).

Ни для одной таблицы нет ограничений. В каждой таблице есть 2 индексированных столбца с общим размером индекса (при 1 млн строк на таблицу) 1 ГБ, что удобно в shared_buffers (2 ГБ). Общий размер данных (при 1 млн строк на таблицу) составляет 12 ГБ, что намного меньше общего объема ОЗУ системы. Это теневая база данных, которую мы можем позволить себе перестроить в экстренном случае, поэтому мы запускаем ее с отключенной функцией fsync.

Похоже, что когда мы находимся в режиме заполнения, мы получаем выгоду от очень малого времени поиска на диске, потому что данные добавляются. Однако, когда мы переключаемся в режим обновления, происходит много поисков (предположительно, для удаления старых строк). Стоимость случайного поиска диска составляет ~ 8 мс (= ~ 125 в секунду).Есть ли способ (без замены оборудования) значительно улучшить производительность операций UPDATE / re-INSERT?

РЕДАКТИРОВАТЬ1: Я провожу тесты производительности на двух различных аппаратных платформах. Цифры, которые я ранее цитировал, были взяты из платформы с более высокими характеристиками. Я только что завершил тестовый запуск на платформе с более низкими характеристиками. В этом тесте я вставляю новые строки как можно быстрее, регистрируя скорость вставки каждые 10 секунд, пока не вставлю 1 миллион строк. На этом этапе мой тестовый сценарий переключается на обновление случайных строк.

Perf results graph

Этот график показывает, что измеренная частота обновления составила ~ 150 обновлений для всех 10 таблиц в секунду во время заполнения, а частота обновления была <10 обновлений для всех 10 таблиц в секунду.

@wildplasser - Машина - это настоящая машина, а не виртуальная машина. Все 10 таблиц имеют следующую схему.

CREATE TABLE objecti_servicea_item1
(
  iss_scs_id text,
  iss_generation bigint,
  boolattr1 boolean,
  boolattr2 boolean,
  boolattr3 boolean,
  boolattr4 boolean,
  boolattr5 boolean,
  boolattr6 boolean,
  boolattr7 boolean,
  boolattr8 boolean,
  boolattr9 boolean,
  boolattr10 boolean,
  boolattr11 boolean,
  boolattr12 boolean,
  boolattr13 boolean,
  boolattr14 boolean,
  boolattr15 boolean,
  boolattr16 boolean,
  boolattr17 boolean,
  intattr1 bigint,
  intattr2 bigint,
  intattr3 bigint,
  intattr4 bigint,
  intattr5 bigint,
  intattr6 bigint,
  intattr7 bigint,
  intattr8 bigint,
  intattr9 bigint,
  intattr10 bigint,
  intattr11 bigint,
  intattr12 bigint,
  intattr13 bigint,
  intattr14 bigint,
  intattr15 bigint,
  intattr16 bigint,
  intattr17 bigint,
  strattr1 text[],
  strattr2 text[],
  strattr3 text[],
  strattr4 text[],
  strattr5 text[],
  strattr6 text[],
  strattr7 text[],
  strattr8 text[],
  strattr9 text[],
  strattr10 text[],
  strattr11 text[],
  strattr12 text[],
  strattr13 text[],
  strattr14 text[],
  strattr15 text[],
  strattr16 text[],
  strattr17 text[]
)
WITH (
  OIDS=FALSE
);
CREATE INDEX objecti_servicea_item1_idx_iss_generation
  ON objecti_servicea_item1
  USING btree
  (iss_generation );
CREATE INDEX objecti_servicea_item1_idx_iss_scs_id
  ON objecti_servicea_item1
  USING btree
  (iss_scs_id );

Выполняемые «Обновления» включают следующий SQL для каждой из 10 таблиц.

DELETE FROM ObjectI_ServiceA_Item1 WHERE iss_scs_id = 'ObjUID39'
INSERT INTO ObjectI_ServiceA_Item1 
VALUES ('ObjUID39', '2', '0', NULL, '0'
, NULL, NULL, NULL, '1', '1', NULL, '0'
, NULL, NULL, NULL, NULL, '0', '1', '1'
, '-70131725335162304', NULL, NULL, '-5241412302283462832'
, NULL, '310555201689715409', '575266664603129486'
, NULL, NULL, NULL, NULL, NULL, NULL
, '-8898556182251816700', NULL, '3325820251460628173'
, '-3434461681822953613'
, NULL
, E'{pvmo2mt7dma37roqpuqjeu4p8b,"uo1kjt1b3eu9g5vlf0d02l6iaq\\\\\\",",45kfns1j80gc7fri0dm29hnrjo}'
, NULL, NULL
, E'{omjv460do8cb7abn8t3eg5b6ki,"a7hrlninbk1rmu6h3rd4787l7f\\\\\\",",24n3ipfua5spma2vrj2aji98g3}'
, NULL
, E'{1821v2n2ermm4jujrucu5tekmm,"ukgst224964uhthkhjj9v189ft\\\\\\",",6dfsaniq9mftvbdr8g1sr8e6as}'
, E'{c2a9gvf0fnd38m8vprlhkp2n74,"ts86vbat12lfr0d7l4tc29k9uk\\\\\\",",32b5j9r5evmrie4h21hi10dpot}'
, E'{18pve4cmcbrjiom9bpvoo1l4n0,"hrqcsane6r0n7u2oj79bj605rh\\\\\\",",32q5n18q3qbkuit605fv47270o}'
, E'{l3bf96shrpnnqgt35m7574t5n4,"cpol4k8296hbdqc9kac79oj0ua\\\\\\",",eqioulmb7vav10lbnc5jg752df}'
, E'{5fai108h163hpjcv0ofgfi7c28,"ci958009ddak3li7bp37slcs8i\\\\\\",",2itstj01tkprlul8f530uhs6s2}'
, E'{ueqfkdold8vc84jllr4b2cakt5,"t5vbea4r7tva091pa8j6886t60\\\\\\",",ul82aovhil1lpd290s14vd0p3i}'
, NULL, NULL, NULL, NULL, NULL)

Обратите внимание, что во время первой фазы моего теста производительности команда DELETE всегда ничего не делает.

@Frank Heikens - В тесте производительности, который я запускаю, обновления выполняются из 10 потоков. Однако обновления назначаются потокам таким образом, чтобы гарантировать, что несколько обновлений одной и той же строки всегда обрабатываются одним и тем же потоком.

5
задан Erwin Brandstetter 30 November 2011 в 22:03
поделиться