【发布时间】:2020-12-16 18:30:21
【问题描述】:
我已经阅读了文档和几篇文章、帖子和线程,但我不确定我是否清楚地理解了这一点。让我们假设这种情况:
1. I have a server side cursor.
2. I set the itersize to 1000.
3. I execute a SELECT query which would normally return 10000 records.
4. I use fetchmany to fetch 100 records at a time.
我的问题是,这是如何在幕后完成的?我的理解是执行了查询,但是服务器端游标读取了1000条记录。除非它滚动超过当前读取的 1000 的最后一条记录,否则游标不会读取下一个 1000。此外,服务器端游标将 1000 保存在服务器的内存中,并一次滚动超过 100,将它们发送到客户端。我也很想知道 ram 消耗会是什么样子?据我了解,如果执行完整查询占用 10000 kb 的内存,则服务器端游标将仅消耗服务器上的 1000 kb,因为它一次仅读取 1000 条记录,而客户端游标将使用 100 kb。我的理解正确吗?
更新 根据我们在回复中的文档和讨论,我希望这段代码一次打印一个包含 10 个项目的列表:
from psycopg2 import connect, extras as psg_extras
with connect(host="db_url", port="db_port", dbname="db_name", user="db_user", password="db_password") as db_connection:
with db_connection.cursor(name="data_operator",
cursor_factory=psg_extras.DictCursor) as db_cursor:
db_cursor.itersize = 10
db_cursor.execute("SELECT rec_pos FROM schm.test_data;")
for i in db_cursor:
print(i)
print(">>>>>>>>>>>>>>>>>>>")
但是,在每次迭代中,它只打印一条记录。我获得 10 条记录的唯一方法是使用 fetchmany:
from psycopg2 import connect, extras as psg_extras
with connect(host="db_url", port="db_port", dbname="db_name", user="db_user", password="db_password") as db_connection:
with db_connection.cursor(name="data_operator",
cursor_factory=psg_extras.DictCursor) as db_cursor:
db_cursor.execute("SELECT rec_pos FROM schm.test_data;")
records = db_cursor.fetchmany(10)
while len(records) > 0:
print(i)
print(">>>>>>>>>>>>>>>>>>>")
records = db_cursor.fetchmany(10)
基于这两个代码sn-ps,我猜在前面提到的场景中发生的情况是给定下面的代码......
from psycopg2 import connect, extras as psg_extras
with connect(host="db_url", port="db_port", dbname="db_name", user="db_user", password="db_password") as db_connection:
with db_connection.cursor(name="data_operator",
cursor_factory=psg_extras.DictCursor) as db_cursor:
db_cursor.itersize = 1000
db_cursor.execute("SELECT rec_pos FROM schm.test_data;")
records = db_cursor.fetchmany(100)
while len(records) > 0:
print(i)
print(">>>>>>>>>>>>>>>>>>>")
records = db_cursor.fetchmany(100)
... itersize 是服务器端的东西。它的作用是,当查询运行时,它设置一个限制,只从数据库加载 1000 条记录。但是 fetchmany 是客户端的事情。它从服务器获得 1000 个中的 100 个。每次 fetchmany 运行时,都会从服务器获取下一个 100。当服务器端的所有 1000 都滚动过去时,接下来的 1000 将从服务器端的 DB 中获取。但我很困惑,因为这似乎不是文档所暗示的。但是话又说回来......代码似乎暗示了这一点。
【问题讨论】:
标签: python-3.x database postgresql psycopg2 server-side