Python В SQL — Теперь я могу загружать данные в 20 раз быстрее
Работа с массивными наборами данных - повседневное дело для большинства специалистов по обработке данных. Не было бы никаких проблем, если бы они сразу передавались потоком в базу данных.
Но, зачастую, случается так, что загрузка данных происходит очень долго. В таких случаях программистам приходится занимать себя другими делами, дожидаясь, пока процесс полностью завершится. Такой вариант подходит далеко не всем!
Если вы действительно хотите сократить это время, вам нужен наиболее оптимальный способ загрузки данных в БД.
Если это предварительно отформатированный файл, я бы предпочёл использовать для него клиентские библиотеки. Например, следующая команда может загрузить ваш CSV-файл в удалённую базу данных Postgres:
Но такое случается редко (по крайней мере, в моей памяти).
Поскольку Python является моим основным языком программирования, я должен загрузить их с Python (возможно, после некоторой предварительной обработки). Поэтому я провёл небольшой эксперимент, чтобы найти самый быстрый способ.
Как оказалось позже, самый быстрый способ не являлся тем, который я использовал на повседневной основе.
Самый ужасный способ: Как не стоит загружать данные
Хотя теперь я уверен, что мне никогда не следует использовать этот метод, изначально я думал, что он сможет мне помочь.
Вот что мы делаем: у меня есть набор данных размером около 500 МБ на диске. Сначала я попытался загрузить его с помощью команды insert в модуле psycopg2:
Я использую декоратор синхронизации, чтобы измерить, сколько времени потребуется для загрузки. Это один из пяти моих любимых декораторов на языке python.
Кроме того, я намеренно сохранил базу данных на своём локальном хостинге. Таким образом, пропускная способность не будет учитывается в уравнении.
Ранее я искренне думал, что это может быть самым быстрым способом загрузки данных. Это потому, что мы используем курсор для вставки данных и фиксации одновременно. Но весь процесс занял очень много времени:
Далее давайте попробуем самый популярный способ.
Плохой способ: использование Pandas to_sql для загрузки массивных наборов данных.
Если вы часто используете Pandas и to_sql API, этот способ может вас удивить.
Я использовал его и продолжаю использовать. Но это всё ещё не лучший способ для больших наборов данных.
Вот мой код. Я использую ту же базу данных и CSV, что и раньше. Я сократил таблицу перед тем, как начать загрузку датасета.
В приведённом выше коде я не использую популярный аргумент method. Установка значения multi ускорит загрузку данных в аналитическую базу данных, такую как Redshift. Но в нашем случае мы используем транзакционную базу данных.
Возвращаясь к главному, загрузка этого метода заняла у нас 376 секунд.
Вывод таков: данный способ почти в 3 раза быстрее, чем предыдущий. Но, как вы уже поняли, есть способы и получше!
Хороший способ: Использование метода COPY
Существует собственный способ загрузки текстовых данных в таблицы SQL. И такие библиотеки, как psycopg2, могут предложить нам его.
Да, мы можем скопировать файл как есть в SQL-таблицы на Python.
Метод copy_from в курсоре использует метод COPY в SQL client API и напрямую загружает файл в SQL. Вместе с этим мы передаём дополнительные аргументы.
Здесь, в данном случае, мы указываем, что столбцы разделяются запятой. Мы также использовали следующий метод, чтобы пропустить первую строку, которая является заголовком таблицы.
Вот результаты:
Поразительные 50 секунд — в 20 раз быстрее, чем при использовании курсора, и почти в 8 раз быстрее, чем метод to_sql Pandas.
Но подождите!
Я сказал, что использую Python, потому что часто выполняю предварительную обработку данных. Два других метода просты. Но как мы будем загружать существующий набор данных в Python runtime с помощью этого метода?
Запись набора данных, существующего в памяти, с использованием COPY
Вот где мы можем извлечь выгоду из буферного метода. Ниже представлен код для быстрой загрузки существующего фрейма данных Pandas в базу данных SQL:
Этот код создаёт объект StringIO с именем csv_buffer, который представляет собой файлоподобный объект, ведущий себя как CSV-файл. Фрейм данных записывается в этот объект с использованием метода to_csv() с index=False и header=False, чтобы исключить индекс и заголовок из выходных данных CSV.
Затем для объекта csv_buffer вызывается метод seek(0), чтобы переместить указатель на файл обратно в начало файлоподобного объекта.
Заключение
Работа с большими наборами данных - это не то же самое, что работа с обычным датасетом. И одной из сложнейших задач здесь является загрузка таких гигантских наборов данных в БД.
Если бы предварительная обработка не требовалась, я бы почти всегда использовал метод Pandas to_sql. Тем не менее, мой эксперимент показывает, что это не лучший способ для больших наборов данных.
Метод COPY - самый быстрый из всех, что я видел до сих пор. Хотя я предлагаю его для пакетной загрузки в контролируемой среде, для повседневных задач to_sql имеет фантастический интерфейс для настройки нескольких режимов загрузки.
Статья была взята из этого источника: