mysql-connector-python的executemany批量插入性能骤降问题咨询
问题原因与解决方案
核心原因
mysql-connector-python在8.0.26版本后,默认连接实现从纯Python模式(use_pure=True)切换到了C扩展模式(use_pure=False),两者对executemany的处理逻辑完全不同:
- 纯Python模式:会自动将多条插入拼接成单条多值INSERT语句(如
INSERT INTO test VALUES (...), (...), ...),仅需一次数据库交互,速度极快。 - C扩展模式:默认逐条执行每条插入语句,每次交互仅插入一行,这直接导致了插入时间从10秒暴涨到550秒。
解决方案
方案1:强制使用纯Python连接
在数据库配置中显式设置use_pure=True,恢复旧版本的批量插入逻辑:
config = { 'user': 'root', 'password': 'password', 'host': '127.0.0.1', 'database':'testdatabase', 'use_pure': True # 新增该行 }
此方法改动最小,能直接让executemany回到高效的批量拼接模式。
方案2:手动构造批量插入SQL
如果不想依赖纯Python实现,可以自行拼接多值INSERT语句,通过execute一次性提交:
# 构造批量插入SQL模板 sql_insert = "INSERT INTO test (id, data) VALUES " + ", ".join(["(%s, %s)"] * len(datalist)) # 将二维元组列表展开为一维参数列表 flat_data = [val for row in datalist for val in row] # 执行批量插入 cur_MySQL.execute(sql_insert, flat_data)
注意:若数据量过大(如超过10万行),建议分批次拼接SQL,避免因语句过长触发数据库限制。
方案3:配置C扩展的批量提交参数
从mysql-connector-python 8.0.30开始,C扩展支持batch_size参数,可控制每次批量提交的行数:
# 创建游标时指定批量大小 cur_MySQL = con_MySQL.cursor(batch_size=1000)
该参数会让C扩展每batch_size行做一次批量提交,虽性能略逊于纯Python模式,但远优于逐条插入。
额外注意事项
你的代码中缺少con_MySQL.commit()语句!MySQL默认关闭自动提交,若不手动提交,插入的数据不会持久化到数据库。建议在executemany后添加提交操作:
cur_MySQL.executemany(sql_insert, datalist) con_MySQL.commit() # 必须添加该行完成提交 cur_MySQL.close() con_MySQL.close()
内容的提问来源于stack exchange,提问作者user2699676
相关产品推荐
相关产品推荐

