加快从 pandas 数据帧到 mysql 的数据插入

Posted

技术标签:

【中文标题】加快从 pandas 数据帧到 mysql 的数据插入【英文标题】:Speeding up data insertion from pandas dataframe to mysql 【发布时间】:2019-12-16 01:25:39 【问题描述】:

我需要使用 sqlalchemy 和 python 将 60000x24 数据帧插入 mysql 数据库 (MariaDB)。数据库在本地运行,数据插入也在本地运行。目前我一直在使用 LOAD DATA INFILE sql 查询,但这需要将数据帧转储到 CSV 文件中,这大约需要 1.5-2 秒。问题是我必须插入 40 个或更多这样的数据帧,所以时间很关键。

如果我使用 df.to_sql,那么问题会变得更糟。每个数据帧的数据插入至少需要 7(最多 30)秒。

下面提供了我正在使用的代码:

sql_query ="CREATE TABLE IF NOT EXISTS table(A FLOAT, B FLOAT, C FLOAT)"# 24 columns of type float
cursor.execute(sql_query)
data.to_sql("table", con=connection, if_exists="replace", chunksize=1000)

执行需要 7 到 30 秒。使用 LOAD DATA,代码如下:

sql_query = "CREATE TABLE IF NOT EXISTS table(A FLOAT, B FLOAT, C FLOAT)"# 24 columns of type float
cursor.execute(sql_query)
data.to_csv("/tmp/data.csv")
sql_query = "LOAD DATA LOW_PRIORITY INFILE '/tmp/data.csv' REPLACE INTO TABLE 'table' FIELDS TERMINATED BY ','; "
cursor.execute(sql_query)

这需要 1.5 到 2 秒,主要是由于将文件转储到 CSV。我可以通过使用 LOCK TABLES 来稍微改进最后一个,但是没有数据被添加到数据库中。所以,我的问题是,有什么方法可以通过调整 LOAD DATA 或 to_sql 来加快这个过程?

更新: 通过使用替代函数将数据帧转储到此答案What is the fastest way to output large DataFrame into a CSV file? 给出的 CSV 文件中 我能够提高一点性能,但不是那么显着。 最好的,

【问题讨论】:

通过循环块并直接在数据库连接上执行手动批量插入命令来尝试手动插入。您还可以利用多处理/多线程。还可以尝试在执行插入之前禁用目标表上的任何索引/约束。 请提供:SHOW CREATE TABLE。如果您直接INSERTed 而不是通过LOAD DATA 将使用的 SQL。无论您是添加到表中还是创建新表。 不知道你的需求,但是你考虑过sqlite3吗?一般来说,它比 MySql/Sql bc 减少开销、文件数据库与 unix 套接字等“快 2 倍 - 10 倍”——这里有一些(旧的)信息。 sqlite.org/speed.html @RickJames,请查看我的更新答案。 if_exists="replace" 指的是什么?如果它检查每一行与其他每一行以避免重复,那是非常慢。而且可能是不必要的。即使是必要的,也可以在加载后快速处理。 【参考方案1】:

如果您知道数据格式(我假设所有浮点数),您可以使用numpy.savetxt() 来大幅减少创建 CSV 所需的时间:

%timeit df.to_csv(csv_fname)
2.22 s ± 21.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)  

from numpy import savetxt
%timeit savetxt(csv_fname, df.values, fmt='%f', header=','.join(df.columns), delimiter=',')
714 ms ± 37.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

请注意,您可能需要预先添加

df = df.reset_index()

使用唯一键对行进行编号并保留.to_csv() 格式样式。

【讨论】:

以上是关于加快从 pandas 数据帧到 mysql 的数据插入的主要内容,如果未能解决你的问题,请参考以下文章

从 pandas 数据帧到多维 numpy 数组以与 tensorflow 兼容

将列表写入 pandas 数据帧到 csv,从 csv 读取数据帧并再次转换为列表而无需字符串

UTF-8编码熊猫数据帧到MySQL

如何用从一个数据帧到另一个数据帧的值替换字符串

对 pandas 数据框的索引查找。为何这么慢?如何加快速度? [复制]

从 mysql 数据库查询中使用 php 时加快 csv 导出