Оптимизация производительности вставки в PostgreSQL

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Чтобы ускорить вставки данных в PostgreSQL, рекомендуется прибегать к массовым операциям с использованием команды COPY. Она позволяет загружать большие объемы данных, существенно уменьшая накладные расходы в сравнении с множественным использованием команды INSERT.

SQL
Скопировать код
COPY my_table FROM '/file.csv' WITH (FORMAT csv);

При работе на Python с PostgreSQL удобно использовать функцию copy_expert из библиотеки Psycopg2. Она позволяет напрямую передать CSV-файлы для массовой загрузки данных:

Python
Скопировать код
import psycopg2

conn = psycopg2.connect(dsn)
cursor = conn.cursor()

with open('data.csv', 'r') as file:
    cursor.copy_expert("COPY my_table FROM STDIN WITH CSV", file)
conn.commit()

Не забывайте об оптимизации параметра work_mem для эффективного использования памяти в процессе вставки данных и задайте размеры пакетов данных для более рационального использования системных ресурсов.

Кинга Идем в IT: пошаговый план для смены профессии

Настраиваем параметры сервера для улучшения стратегии вставки

Для сокращения числа контрольных точек (checkpoint) во время массовой загрузки данные, следует настроить параметры PostgreSQL, вроде max_wal_size. Если вы установите synchronous_commit в положение off, транзакция завершится успешно ещё до того, как записи WAL будут записаны на диск. Это увеличит скорость записи данных:

SQL
Скопировать код
ALTER SYSTEM SET synchronous_commit TO off;

Рациональное управление Журналом Предзаписи (WAL), включая увеличение параметра commit_delay при работе с несколькими параллельными транзакциями, делает групповую фиксацию более эффективной. Размещение файлов WAL на отдельном диске также положительно сказывается на производительности ввода-вывода.

Оптимизация таблиц и индексов для более быстрой загрузки данных

Для ускорения вставки данных можно воспользоваться обработкой в режиме UNLOGGED таблиц, что временно обеспечивает исключение затрат на запись операций в WAL:

SQL
Скопировать код
CREATE UNLOGGED TABLE my_table_temp AS SELECT * FROM my_table WITH NO DATA;

После массовых операций вставки не забывайте удалять и создавать заново индексы для поддержания их оптимальной эффективности. После вставки данных также важно активировать триггеры:

SQL
Скопировать код
DROP INDEX my_index;
-- Операция вставки
CREATE INDEX my_index ON my_table USING btree (my_column);

Визуализация

Представьте, что база данных — это шоссе, где даными являются автомобили:

Markdown
Скопировать код
Обычное передвижение:   🚗 ➡️ 🚗 ➡️ 🚗 ➡️ 🚗 ➡️ 🚗 ➡️ (Медленное добавление данных)

Чтобы оптимизировать вставку, выберите быстрый путь:

Markdown
Скопировать код
Экспресс-маршрут для больших данных: 🚀🚗🚗🚗🚗🚗 (Быстрая массовая вставка)
                                        🏁 Финиш (Индексация после вставки)
  1. Массовая вставка: Запустите все автомобили одновременно.
  2. Задержка индексации: Устанавливайте указатели направления (индексы) после гонок.

Результат: данные быстрее попадают из точки А в точку Б! 🏎️💨

Выбираем правую полосу: аппаратные соображения

Переход на SSD высокого уровня существенно увеличит скорость записи данных. Разделение дисковой нагрузки между базой данных и WAL поможет распределить нагрузку на ввод-вывод. Улучшение аппаратных ресурсов, включая увеличение объема оперативной памяти, значительно повысит общую производительность системы.

Мощный ход: использование современных форматов данных

Для максимизации скорости загрузки данных используйте команду COPY с бинарными форматами данных. В Python возможно применение бинарной загрузки, предоставляемой такими библиотеками, как psycopg2.

Эффективные и стильные вставки в Python

Пользователи Python могут ускорить процесс с помощью предварительно подготовленных SQL-выражений. Не забывайте отключать auto-commit для экономии ресурсов, затрачиваемых на транзакции, и применяйте такие подходы, как SQLBulkOperations.

Python
Скопировать код
cursor.execute('PREPARE bulk_insert (int, text) AS INSERT INTO my_table VALUES ($1, $2);')

for record in records:
    cursor.execute('EXECUTE bulk_insert (%s, %s)', record)
    
conn.commit()

Совершенствуем стратегии индексации для UUID

При работе с UUID важно использовать функции, вроде gen_random_uuid(). Однако следует помнить о последствиях их использования для процесса индексации и потенциальной перестройке данных, которая может замедлить скорость вставок данных.

Полезные материалы

  1. PostgreSQL: Документация: 16: COPY — детальное описание команды COPY, необходимой для выполнения массовых вставок.
  2. Самый быстрый способ загрузки данных в PostgreSQL с использованием Python | Haki Benita — эффективные методы настройки PostgreSQL для массовых загрузок на Python.
  3. Inserts – PostgreSQL wiki — страница wiki PostgreSQL с советами по ускорению вставок данных.
  4. PostgreSQL Performance Tuning – CYBERTEC — комплексное руководство по финесустройке производительности от экспертов CYBERTEC.
  5. Блог Timescale — сборник лучших практик для массовой загрузки данных в PostgreSQL.