我正在使用Python中的MySQLdb模块与数据库进行交互。我遇到了这样一种情况:有一个非常大的列表(成千上万个元素),我需要将其作为行插入到表格中。
目前,我的解决方案是生成一个大的INSERT
语句,并执行它。
有更聪明的方法吗?
有一种更聪明的方法。
批量插入的问题在于,默认情况下,自动提交已启用,这导致每个insert
语句在开始下一个插入之前都会保存到稳定存储器中。
正如手册页所述:
默认情况下,MySQL 运行时启用自动提交模式。这意味着一旦您执行更新(修改)表的语句,MySQL 就会将更新保存到磁盘上以使其永久化。要禁用自动提交模式,请使用以下语句:
SET autocommit=0;
将autocommit变量设置为零以禁用自动提交模式后,对于事务安全表(如InnoDB、BDB或NDBCLUSTER),所做的更改不会立即永久保存。您必须使用COMMIT将更改存储到磁盘上,或者使用ROLLBACK忽略更改。
这是关系型数据库系统的常见功能,它默认保证了数据库的完整性。这会使得批量插入操作需要大约1秒每次而不是1毫秒。另一种方法是尝试制作一个过大的插入语句,以此冒着超载SQL解析器的风险来实现单个提交。
insert
中插入所有数据?这会不必要地给内存带来负担,在制作这个大的insert
字符串和执行它时也会如此。如果要插入的数据非常非常大,这也不是一个很好的解决方案。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
。像msw
说的那样将它设置为False
。
SET autocommit = 0;
来关闭提交(或者在您的python程序中这样做,请使用cur.execute('SET autocommit = 0'); con.commit()
)。 - Pushpak Dagadefor data in your_data_list: cur.execute("data you want to insert: %s" %data)
,会打开 SQL 注入攻击的漏洞。最好使用以下方式:for data in your_data_list: cur.execute("data you want to insert: %s",item 1, item 2)
(在 SQL 语句字符串后面的每个逗号都将使用项目替换 SQL 字符串中的 ?
)
请参阅 https://mkleehammer.github.io/pyodbc/,查看“插入数据”下的更多信息。
愉快编码! - Colbymysqld --max_allowed_packet=32M
innodb_buffer_pool_size
对于我的事务大小来说太小了,通过增加它,我为批量插入实现了 +40% 的加速。请参见:https://dev.mysql.com/doc/refman/5.7/en/innodb-buffer-pool.html - jlh