Что замедляет мой массовый импорт PostgreSQL?
Поскольку его легко установить в стабильной Debian, я решил использовать PostgreSQL 9.6 для создания хранилища данных для некоторых данных, которые мне нужно обработать. Первым шагом является загрузка данных в базу данных с минимальными преобразованиями, в основном исправляя некоторые известные ошибки форматирования и то, как представлены логические значения. Я проверил, что эти исправления эффективны: написание n
строк на диск занимает время, пропорциональное n
,
Тем не менее, массовая загрузка этих данных с использованием PostgreSQL COPY FROM
(не важно как; \copy
или psycopg2 copy_expert
, или же COPY FROM '/path/to/data.csv'
) занимает суперлинейное количество времени. Асимптотическая сложность времени кажется несколько лучше, чем O(exp(sqrt(n)))
, Это сложность, когда я уже:
- Установите уровень изоляции на
READ UNCOMMITTED
, а также - Установите ограничение первичного ключа в
DEFERRED
,
Вот что я вижу с одним из худших нарушителей, с таблицей 17M строк:
Отключение fsync
ускоряет процесс в 10 раз, поэтому ввод-вывод, очевидно, является огромным узким местом. Однако, кроме этого, временное поведение не сильно меняется:
Эта проблема полностью исчезает, когда я использую суррогатный ключ вместо бизнес-ключа: когда я использую столбец целых чисел с автоинкрементом в качестве первичного ключа, прием внутрь Θ(n)
снова, что я и хотел. Таким образом, у меня есть не только идеальный обходной путь для моей проблемы, но я также знаю, что сложный первичный ключ является виновником (бизнес-ключ обычно является кортежем коротких столбцов VARCHAR).
Однако я хотел бы понять, почему PostgreSQL так долго потребляет данные, когда они вводятся с помощью бизнес-ключа, так что я лучше понимаю свои инструменты. В частности, я понятия не имею, как отладить этот процесс приема пищи, потому что EXPLAIN
не работает на COPY
, Это может быть из-за того, что сортировка данных в хранилище для составных первичных ключей занимает больше времени, или из-за индексации, или из-за того, что ограничение первичного ключа все еще сохраняется NOT DEFERRED
; если обходной путь не будет таким эффективным или нежелательным по другим причинам, как я могу обнаружить, что на самом деле здесь происходит?