我编写了一个遍历大型数据库表的脚本。(~150K 行。)为了避免使用太多内存,我使用了这个windowed_query 方法。我的脚本是这样的:
query = db.query(Table)
count = 0
for row in windowed_query(query, Table.id, 1000):
points = 0
# +100 points for a logo
if row.logo_id:
points += 100
# +10 points for each image
points += 10 * len(row.images) #images is a SQLAlchemy one-to-many relationship
#...The script continues with much of the same...
row.points = points
db.add(row)
count += 1
if count % 100 == 0:
db.commit()
print count
request.db.commit()
当试图在 CentOS 服务器上运行它时,它会在被内核杀死之前通过 9000 行,因为它正在使用 ~2GB 的内存。
在我的 Mac 开发环境中,它就像一个魅力,即使它运行在完全相同版本的 Python (2.7.3)、SQLAlchemy (0.7.8) 和 psycopg2 (2.4.5) 上。
使用 memory_profiler 进行一些简单的调试:在 Linux 上,每条查询数据库的代码都会少量增加内存,而且增长从未停止。在 Mac 上,也发生了同样的事情,但在增长了 ~4MB 之后,它趋于平稳。就好像在 Linux 上没有任何东西被垃圾收集一样。(我什至尝试每 100 行运行一次 gc.collect()。什么也没做。)
有人知道发生了什么吗?