Windows中的Python:使用pyodbc的大量插入导致内存泄漏

Windows中的Python:使用pyodbc的大量插入导致内存泄漏,python,memory-leaks,pyodbc,Python,Memory Leaks,Pyodbc,我正在尝试在windows上使用python填充MS SQL 2005数据库。我插入了数百万行,到700万行时,我使用了近1GB的内存。以下测试每插入100k行消耗4兆RAM: import pyodbc connection=pyodbc.connect('DRIVER={SQL Server};SERVER=x;DATABASE=x;UID=x;PWD=x') cursor=connection.cursor() connection.autocommit=True while 1:

我正在尝试在windows上使用python填充MS SQL 2005数据库。我插入了数百万行,到700万行时,我使用了近1GB的内存。以下测试每插入100k行消耗4兆RAM:

import pyodbc
connection=pyodbc.connect('DRIVER={SQL Server};SERVER=x;DATABASE=x;UID=x;PWD=x')
cursor=connection.cursor()
connection.autocommit=True
while 1:
    cursor.execute("insert into x (a,b,c,d, e,f) VALUES (?,?,?,?,?,?)",1,2,3,4,5,6)
mdbconn.close()

黑客解决方案:我最终使用多处理模块生成了一个新进程来返回内存。仍然不明白为什么以这种方式插入行会消耗这么多内存。有什么想法吗?

也许每百万行左右关闭并重新打开一次连接


当然,这不能解决任何问题,但如果你只需要做一次,你就可以继续生活

尝试为每个插入创建一个单独的光标。每次通过循环重用游标变量,以隐式地取消引用上一个游标。在每次插入后添加connection.commit


您可能只需要时间这样简单的东西。在每个循环的底部睡眠(0)以允许垃圾收集器运行。

您也可以在导入
gc
模块后,每隔一段时间尝试使用
gc.collect()
强制垃圾收集一次

另一个选项可能是使用cursor.executemany(),看看这是否解决了问题。然而,
executemany()
最糟糕的地方是它需要一个序列而不是一个迭代器(因此不能将其传递给生成器)。我想先试试垃圾收集器


编辑:我刚刚测试了你发布的代码,我没有看到同样的问题。您使用的是pyodbc的旧版本吗?

即使是我也遇到了同样的问题

我必须读取50多个XML文件,每个文件大约300MB,然后将它们加载到SQLServer2005中

我尝试了以下方法:

通过取消引用使用同一光标

关闭/打开连接

将连接设置为“无”

最后,使用流程模块引导每个XML文件加载

现在,我使用IronPython-System.Data.SqlClient替换了该流程


这提供了更好的性能和更好的接口。

我也有同样的问题,它看起来像是带有参数化插入的pyodbc问题:


暂时切换到填充了VALUES子句的静态插入可以消除泄漏,直到我尝试从当前源生成。

您尝试过手动提交事务吗?这看起来有点像这些都没有被提交给db。谢谢。设置connection.autocommit=False并使用connection.commit()手动提交对内存使用没有影响。这个问题解决了吗?我也有同样的问题谢谢。我尝试了connection.close()和connection=pyodbc.connect(),每插入10000次。看来内存使用率会上升,谢谢你,freegnu。创建单独的光标没有任何效果。我在每1000次插入后都尝试了time.sleep(1),但这也没有任何效果——每次插入后都是time.sleep(0)。我使用pymssql进行开发,没有看到在生产中使用mx.odbc.windows时看到的一半问题和限制。我猜pyodbc也有问题。您可能想尝试一下pymssql,这就解决了它。但愿我能得到15分,这样我就可以投票支持这一点了。谢谢!看来最新的代码解决了这个问题,没有解决办法。