У меня проблема с пропускной способностью последовательностей 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 миллион строк.На этом этапе мой тестовый скрипт переключается на обновление случайных строк.
Этот график показывает, что измеренная частота обновления составила ~ 150 обновлений для всех 10 таблиц в секунду во время заполнения и частоты обновлениябыло <10 обновлений для всех 10 таблиц в секунду. </p>
@ 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)
Обратите внимание, что на первом этапеиз моего теста perf команда DELETE всегда ничего не делает.
@ Frank Heikens - В тесте perf, который я запускаю, обновления выполняются из 10 потоков.Однако обновления назначаются потокам таким образом, чтобы гарантировать, что несколько обновлений в одной и той же строке всегда обрабатываются одним потоком.