【发布时间】: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"指的是什么?如果它检查每一行与其他每一行以避免重复,那是非常慢。而且可能是不必要的。即使是必要的,也可以在加载后快速处理。
标签: python mysql pandas performance mariadb