Как выполнить больший. sql файл в базе данных быстрее? - PullRequest
0 голосов
/ 24 января 2020

В настоящее время я имею дело с файлом 4 ГБ dump.sql, поэтому я попытался создать из него базу данных, используя mysql консоль сервера.

Это команды, которые я использовал в терминале :

mysql -u username -ppassword

mysql> create database test;
mysql> use test;
mysql> source dump.sql

Мне потребовалось 3 часа, чтобы завершить процесс. После этого я смог без проблем получить доступ к созданной базе данных.

Характеристики: 16-ядерный процессор Intel, 60 ГБ ОЗУ, 120 ГБ ssd.

Дело в том, что у меня есть файл дампа 8 ГБ или тем более я ищу более быстрый способ выполнения скрипта. sql. Я не уверен, что первый метод оптимизирован.

Я также пытался сделать это в python,

import mysql.connector

conn = mysql.connector.connect(user='root', password='root')
cursor = conn.cursor()

cursor.execute(open('dump.sql').read(), multi=True)
conn.commit()

---------------------------------------------------------------------------
OverflowError                             Traceback (most recent call last)
<ipython-input-7-b5009cf1d04b> in <module>
----> 1 cursor.execute(open('dump.sql').read(), multi=True)

~/miniconda3/lib/python3.7/site-packages/mysql/connector/cursor_cext.py in execute(self, operation, params, multi)
    264             result = self._cnx.cmd_query(stmt, raw=self._raw,
    265                                          buffered=self._buffered,
--> 266                                          raw_as_string=self._raw_as_string)
    267         except MySQLInterfaceError as exc:
    268             raise errors.get_mysql_exception(msg=exc.msg, errno=exc.errno,

~/miniconda3/lib/python3.7/site-packages/mysql/connector/connection_cext.py in cmd_query(self, query, raw, buffered, raw_as_string)
    487             self._cmysql.query(query,
    488                                raw=raw, buffered=buffered,
--> 489                                raw_as_string=raw_as_string)
    490         except MySQLInterfaceError as exc:
    491             raise errors.get_mysql_exception(exc.errno, msg=exc.msg,

OverflowError: size does not fit in an int

Это вернуло ошибку переполнения для int. Я не смог найти никакой помощи, чтобы преодолеть эту ошибку онлайн.

1 Ответ

1 голос
/ 24 января 2020

Импортирование файла дампа, созданного с помощью mysqldump, очень медленно. Он должен выполнять SQL операторов последовательно в одном потоке, поэтому не имеет значения, сколько ядер у вас на сервере. Будет использоваться только одно ядро.

Маловероятно, что вы можете написать python скрипт, который будет выполнять импорт быстрее, так как вы все равно обязаны запускать операторы SQL последовательно.

Также в файле дампа содержатся некоторые клиентские команды, которые не реализован в вашем скрипте python, а синтаксический анализатор MySQL SQL не распознает. Вы не можете выполнять эти встроенные команды клиента, используя SQL API. См. https://dev.mysql.com/doc/refman/8.0/en/mysql-commands.html

Один из вариантов - выполнить дамп с использованием mysqldump --tab, который сбрасывает разделенные табуляцией данные в один файл на таблицу вместо одного огромного. sql файла для всех таблиц.

Затем импортируйте эти файлы с помощью mysqlimport. Внутри это использует LOAD DATA INFILE, что аналогично команде PostgreSQL COPY, упомянутой Крисом в комментарии выше.

По желанию mysqlimport --use-threads, поэтому он импортирует таблицы параллельно. По моему опыту, вы получите убывающую отдачу, если попытаетесь использовать более 4 одновременных потоков, даже если у вашего процессора больше ядер, потому что вы максимально увеличите скорость записи MySQL.

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

Чтобы сделать это, вам, в основном, придется разработать свой собственный оригинальный клиент для загрузки данных, который разделяет данные и загружает их параллельно. Сколько времени вы готовы вложить в это, чтобы не ждать 6 часов для большей загрузки данных?

...