psycopg 何时执行光标命令



我正在使用psycopg2对数据库进行简单的查询。目前它是一个只有几个条目的测试数据库,但我担心我正在执行的命令在迁移到可能很大的真实数据库时会变得过于内存密集。

import psycopg2
connection = psycopg2.connect('<database_url>')
cur = connection.cursor()
cur.execute("SELECT * FROM test;")
entries = cur.fetchmany(limit)

所以我的问题是这个。psycopg2 是在execute行运行数据库查询(在这种情况下,大型数据库将消耗大量客户端内存(,还是直到fetchmany行才运行查询(在这种情况下,我可以控制 python 内存消耗(。

如果是前者,大概我需要将我的 SQL 查询更改为仅返回x行。

为了详细说明@Arihant的注释,该语句在调用execute时运行。这将触发数据库上的内存消耗。您可能不需要担心这一点 - 适度大小的数据库可以有效地处理数百万行;使用了很多优化和内存管理策略,尽管如果查询本身变得复杂,内存开销可能会成为问题。

一旦您开始获取数据,客户端内存就会发挥作用。我使用以下两种策略之一来控制内存使用:

使用fetchmany()而不是fetchall()(与将光标用作可迭代对象相比(。limit/offset查询可以获得相同的基本结果,但您需要执行许多此类查询来浏览大型数据集,这会在服务器上产生不必要的成本。

with conn.cursor() as stmt:
stmt.execute('select * from big_table')
rows = stmt.fetchmany(10000)
while rows:
for row in rows:
#do something clever with the row
rows = stmt.fetchmany(10000)

使用服务器端游标。这在服务器上的开销略高,但将使客户端上的内存完全平坦(除非您尝试保存所有记录。

with conn.cursor('my_cursor') as stmt:
stmt.execute('select * from big_table')
for row in stmt:
#do something clever with the row

无论采用哪种方法,关键是如何处理返回的记录。如果您尝试将它们保存在内存中,则会耗尽内存。以块为单位处理数据。

最新更新