【发布时间】:2018-12-22 19:09:12
【问题描述】:
我正在使用 Python3 在 MySQL 中插入数百万行,但我发现内存使用量不断增长,最终达到 64GB。我试图诊断问题,这里是问题的重现:假设我有 100 个 CSV 文件。每个文件包含 50000 行,我想将它们插入数据库。这是一个示例代码:
import mysql.connector
insert_sql = ("INSERT INTO table (Value) VALUES (%s)")
for i in range(100):
cnx = mysql.connector.connect(user='root', password='password', host='127.0.0.1', database='database')
cursor = cnx.cursor()
# Insert 50000 rows here
for j in range(50000):
cursor.execute(insert_sql, (j,))
cnx.commit()
cursor.close()
cnx.close()
print('Finished processing one file')
print('All done')
数据库只包含 1 个 2 列的表:
CREATE TABLE `table` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`Value` int(11) NOT NULL,
PRIMARY KEY (`Id`)
)
环境:Mac OS Sierra; Python 3.6.x; MySQL 8.0.1; mysql-connector-python 8.0.11
我知道内存应该在提交之前增长,因为更改是缓冲的。但我认为它会在提交后减少。但是,没有。因为在我的实际应用程序中,我有数千个文件,每个文件 100MB,我的内存会爆炸。
我在这里做错了吗? (我是数据库新手)如何控制内存使用?任何建议将不胜感激!
编辑:我也根据 cmets 和答案尝试了以下代码,但它仍然不起作用:
import mysql.connector
insert_sql = ("INSERT INTO table (Value) VALUES (%s)")
for i in range(100):
cnx = mysql.connector.connect(user='root', password='password', host='127.0.0.1', database='database')
cursor = cnx.cursor()
params = [(j,) for j in range(50000)]
# If I don't excute the following insertion, the memory is stable.
cnx.executemany(insert_sql, params)
cnx.commit()
cursor.close()
del cursor
cnx.close()
del cnx
print('Finished processing one file')
print('All done')
【问题讨论】:
-
您是否尝试过
executemany()而不是循环中的许多execute()? -
也尝试使用
?而不是%s -
@AndrejKesely 是的,我尝试将所有参数放在一个列表中并使用
executemany()插入它们,但内存仍在不断增长。 -
@RedEyed 谢谢,但我试过
?,它也不起作用。
标签: python mysql python-3.x memory-leaks mysql-connector-python