我正在使用Python中的MySQLdb模块来与数据库交互。我有一个情况,就是有一个非常大的列表(数以万计的元素),我需要将其作为行插入到表中。Python + MySQL - 批量插入
我现在的解决方案是生成一个大的INSERT
语句作为字符串并执行它。
有没有更聪明的方法?
我正在使用Python中的MySQLdb模块来与数据库交互。我有一个情况,就是有一个非常大的列表(数以万计的元素),我需要将其作为行插入到表中。Python + MySQL - 批量插入
我现在的解决方案是生成一个大的INSERT
语句作为字符串并执行它。
有没有更聪明的方法?
有一个更聪明的方法。
大容量插入的问题是默认情况下autocommit is enabled因此导致每个insert
语句在下一次插入启动之前被保存到稳定存储区。
由于手册页注释:
默认情况下,MySQL的运行启用了自动提交 模式。这意味着,当您执行 更新(修改)表时,尽快 ,MySQL 将更新存储在磁盘上以使其永久为 。要禁用自动提交模式, 使用下面的语句:
SET autocommit=0;
由 自动提交变量设置为零,禁用 自动提交模式后,改变 事务安全表(如 那些InnoDB的,BDB或NDBCLUSTER) 不会立即生效。 您必须使用COMMIT将您的 更改存储到磁盘或ROLLBACK以忽略 的更改。
这是RDBMs系统的一个非常普遍的特性,它假定数据库完整性是最重要的。它确实使批量插入每个插入的次数为1s,而不是1ms。制作超大插入语句的替代方法试图实现这种单次提交有可能重载SQL解析器的风险。
如果你不得不插入非常大量的数据,你为什么要试图将它们全部插入到一个单一的insert
? (这将不必要地在你的内存中加载这个大的insert
字符串,同时也执行它。如果你的数据插入非常大,这不是一个很好的解决方案。)
为什么不你在db中为每个insert
命令添加一行,并使用for...loop
放置所有行,并在最后提交所有更改?
con = mysqldb.connect(
host="localhost",
user="user",
passwd="**",
db="db name"
)
cur = con.cursor()
for data in your_data_list:
cur.execute("data you want to insert: %s" %data)
con.commit()
con.close()
(相信我,这实在是快,但如果你是越来越慢的结果那么就意味着你的autocommit
必须True
。将它设置为False
,因为msw
表示。)
从1.2.0开始,MySQLdb根据DB-API标准(PEP-249)的要求默认禁用自动提交。来源:http://mysql-python.sourceforge.net/FAQ.html – mikewaters
如果你觉得你的插入仍然比他们应该慢,确保也调整你的MySQL服务器设置。在我的情况下,我的'innodb_buffer_pool_size'对于我的交易规模来说太小了,通过提高它,我实现了批量插入+ 40%的加速。请参阅:https://dev.mysql.com/doc/refman/5.7/en/innodb-buffer-pool.html – jlh