#python #postgresql #performance
#python #postgresql #Производительность
Вопрос:
Набор данных состоит из двух папок, каждая из которых содержит 180 файлов CSV. Мой скрипт на Python будет считывать два CSV-файла из этих двух папок каждый раз в течение 180 циклов.
После считывания данных и некоторой обработки данные из двух файлов CSV объединяются в один список с формой [(1,1), (1,2), (1,3), ...]
. В списке будет около 3,000,000,000
кортежей.
Сначала я пересмотрел некоторые параметры (как показано ниже) postgresql.conf
и попытался сразу вставить весь список в DB с помощью executemany
, это заняло около 30,000
секунд, что заняло бы у меня два месяца, чтобы их прочитать. Затем я попытался разделить список на 30 вложенных списков и прочитать их один за другим. Чтение каждого вложенного списка заняло около 230
секунд, что намного быстрее, но все равно займет 15 дней.
Я, вероятно, буду использовать многопроцессорную обработку, поскольку у меня больше оперативной памяти и процессоров для использования (один процесс использует 35 ГБ памяти, я думаю, я попытаюсь использовать три процесса). Но я хотел бы спросить, могу ли я как-то оптимизировать параметры DB для лучшей производительности вставки на этом шаге? Поскольку в документации psql мало говорилось о настройке параметров, за исключением того, что установка share_buffers
на 25% оперативной памяти повысила бы производительность.
Заранее спасибо!
Мои текущие параметры, которые не соблюдаются по умолчанию:
shared_buffers = 10 GB
temp_buffers = 1GB
max_wal_size = 1GB
effective_cache_size = 20GB
work_mem = 2GB
maintenance_work_mem = 4GB
ENV: Redhat, оперативная память: 150 ГБ, количество ядер: 40
Комментарии:
1. Вы пробовали проводить сравнительный анализ этого? psycopg.org/docs/cursor.html#cursor.copy_from
2. @MikeOrganek Нет, у меня нет. Потому что я должен прочитать файлы и выполнить некоторую обработку данных. Будет ли быстрее, если я запишу данные в CSV после обработки, затем прочитаю данные из CSV и вставлю в БД?
3. Когда вы выполняете обработку данных, запишите результаты в строку, а затем используйте
StringIO
для обработки строки как файла, когда вы это делаетеcopy_from()
.4. Из документов ( psycopg.org/docs/cursor.html#cursor.executemany ): «Предупреждение В текущей реализации этот метод не быстрее, чем выполнение execute() в цикле. Для повышения производительности вы можете использовать функции, описанные в Fast execution helpers.»