【问题标题】:psycopg2 using too much memorypsycopg2 使用太多内存
【发布时间】:2022-01-10 08:37:26
【问题描述】:

我有一个非常大的表(3.7 GB)存储在我使用 psycopg2 加载的 PostgreSQL 数据库中,代码如下:

conn = psycopg2.connect(host="localhost", port = 5432, database="postgres", user="postgres", password="root")

cur = conn.cursor('cursor1')
cur.itersize = 10000 
cur.execute("""SELECT * FROM customers""")
query_results = cur.fetchall()
cur.close()
conn.close()

Python第一次加载表使用13GB内存,每次再次运行这段代码,内存使用量都会增加,直到变成99%;然后再次下降到 13GB 水平。此外,每次查询需要更长的时间来执行:第一次 34 秒,第二次 46 秒,并且在接下来的运行中保持约 45 秒。

我已经搜索了解决方案,this answer 似乎提供了答案,但添加 itersize 对我也不起作用;内存使用保持不变

我应该怎么做才能减少内存使用?我用了 gc.collect() 也没有用。

我在 Windows10 机器上使用 Python 3.9 和 PostgreSQL 14,我有 32GB RAM。

【问题讨论】:

  • 您真的需要选择表格的所有行和所有列吗?换句话说,您的实际用例是什么?
  • 如果你需要为所有的客户做一些操作,那么用一些batching logic来做,例如。特定 ID 范围内的客户,或名称从“A”到“C”,然后从“D”到“F”,这样您不需要只需带上所有 从那个大表到你的客户端的记录。
  • 上述机制使您能够利用索引(如果有的话),如果您适当地构建您的 WHERE 子句。
  • @AKX 在某些时候我会根据整个表格进行一些计算。但我的主要观点不同:为什么 3.7GB 表占用 13GB 内存?我知道程序大小将超过 3.7GB,但不是 13GB。我猜游标占用了内存然后不释放它,但不知道该怎么做。
  • @AnandSowmithiran 正如我所说,主要问题是表在 Python 内存中的大小是其大小的 4 倍,我想解决这个问题。

标签: python postgresql psycopg2


【解决方案1】:

以 python 形式保存数据的大约 4 倍扩展似乎是正确的(使用 pgbench_accounts 作为基准)。 Python 自动管理内存,不是特别有效。如果你想从内存使用中对大脑进行微观管理,你应该用 C 编写,而不是 python。

当您希望数据全部存储在内存中时,使用命名游标读取数据几乎毫无意义。现在,如果您想通过 python 流式传输数据,例如使用for row in cur,那么它自己会节省大量内存,而在此之上使用命名游标会节省更多。

您关于每次运行时使用越来越多内存的评论没有任何意义。您的代码只执行一次 SQL。您不能期望对代码的不可见部分进行智能评论。

【讨论】:

    猜你喜欢
    • 2015-06-18
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    相关资源
    最近更新 更多