python - 如何更快地将更大的.sql文件执行到数据库?

标签 python mysql sql mysql-python

我目前正在处理一个 4gb dump.sql 文件,因此我尝试使用 mysql 服务器控制台从中创建一个数据库。

这些是我在终端中使用的命令:

mysql -u username -ppassword

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

我花了大约 3 个小时才完成这个过程。之后我就可以毫无问题地访问创建的数据库。

规范: 16 核英特尔处理器、60GB 内存、120GB 固态硬盘。

问题是我有一个 8GB 或更大的转储文件,所以我正在寻找任何更快的方法来执行 .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 的溢出错误。我在网上找不到任何帮助来克服此错误。

最佳答案

导入由 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 ,它类似于 Chris 在上面的评论中提到的 PostgreSQL COPY 命令。

可选地,mysqlimport --use-threads 因此它可以并行导入表。根据我的经验,如果您尝试使用超过 4 个并发线程,即使您的 CPU 具有更多内核,您的返回也会递减,因为您将最大化 MySQL 写入数据的速率。

但是并行加载仍然会串行加载每个表,它不会被分成几部分。因此,如果您的数据由一个非常大的表和一组较小的表组成(这是一个非常典型的场景),您仍然会受到最大的单个表的约束。

要做到这一点,您基本上必须开发自己的原始数据加载客户端,以并行拆分数据和加载。您愿意为此投入多少开发时间,以避免等待更大的数据负载 6 个小时?

关于python - 如何更快地将更大的.sql文件执行到数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59887391/

相关文章:

php - mysql_real_escape_string 反转?

mysql - 选择输入的第一部分在列中的位置

python - 使用 Python 和 PostgreSQL 管理多个类别树

mysql - 停止在 mysql 中重复列值

c# - 我可以在 EF core asp.net 中使用相同模型创建多个表吗

php - 如何使用 php 从 mysql 表中存储的出生日期计算年龄

python - 多 GPU/Tower 设置 Tensorflow 1.2 Estimator

python - 关于 Python 中使用的 DOM 解析器的问题

python - 如何对不同的迭代值求和?

动态类变量名的 pythonic 方法(ala PHP 的 $$var)