Я использую программное обеспечение, которое генерирует порядка нескольких миллионов небольших фрагментов данных и должно как можно быстрее поместить их в БД.
В настоящее время я использую подготовленные операторы иоптимизировал БД (Postgres 9.6) для небольших вставок и получил довольно хорошую производительность.Но мне интересно, если бы это ускорило ситуацию еще больше, если бы вместо подготовленных утверждений я собрал бы данные, чтобы не вставлять каждую строку по отдельности.
Я провел некоторое исследование по этому вопросу, ноне нашел окончательного ответа.
Мои данные достаточно малы (5-10 значений в строке) и чисто числовые (то есть без строк, но представляют собой целые числа, числа с плавающей запятой и логические значения).В моих таблицах в качестве первичного ключа используются серийные номера, но нет других индексов.Я вставляю в несколько таблиц, которые связаны внешними ключами.Сейчас у меня есть пять подготовленных заявлений, по одному на каждую таблицу.Каждый оператор вставляет одну строку, потому что я не могу заранее сказать, сколько строк я получу.
Мои операторы тривиальны - без математики, условий или чего-либо, в основном все они выглядят так:
conn.prepare("INSERT INTO event
(sc_id, r_id, th_id, tc, rs, is_te, is_le, total)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
RETURNING id")
Я использую Postgresql 9.6 на быстром хранилище, которое я уже тестировал и которое оказалось узким местом.Мое программное обеспечение написано на Rust и может генерировать данные примерно на два порядка быстрее, чем БД может его хранить.Я уже увеличил производительность в 4 раза за счет оптимизации конфигурации Postgres, и я думаю, что это большая часть того, что я получу от этого.
Я также работаю в параллельных потоках, каждый из которых вставляет наборы данных, которыенезависимы друг от друга.
Сервер БД находится на той же физической машине, что и генератор данных, и я подключаюсь через сокет, а не через TCP.