为什么postgresql不会立即开始返回行?

cod*_*ape 6 python sql postgresql sqlalchemy

以下查询立即返回数据:

SELECT time, value from data order by time limit 100;
Run Code Online (Sandbox Code Playgroud)

如果没有limit子句,服务器开始返回行需要很长时间:

SELECT time, value from data order by time;
Run Code Online (Sandbox Code Playgroud)

我通过使用查询工具(psql)和使用API​​查询来观察这一点.

问题/问题:

  • 在开始返回行之前,服务器必须执行的工作量对于两个select语句应该相同.正确?
  • 如果是这样,为什么案例2有延迟?
  • 是否存在一些我不理解的基本RDBMS问题?
  • 有没有办法让postgresql开始将结果行返回给客户端而不会暂停,对于案例2也是如此?
  • 编辑(见下文).看起来setFetchSize是解决这个问题的关键.在我的例子中,我使用SQLAlchemy从python执行查询.如何为单个查询设置该选项(由执行session.execute)?我使用psycopg2驱动程序.

该列time是主键,BTW.

编辑:

我相信这个摘自JDBC驱动程序的文档描述了问题和解决方案的提示(我仍然需要帮助 - 请参阅上面的最后一个项目列表项目):

默认情况下,驱动程序立即收集查询的所有结果.这对于大型数据集来说可能不方便,因此JDBC驱动程序提供了一种将ResultSet基于数据库游标并仅获取少量行的方法.

将代码更改为游标模式就像将Statement的获取大小设置为适当的大小一样简单.将获取大小设置为0将导致所有行被缓存(默认行为).

// make sure autocommit is off
conn.setAutoCommit(false);
Statement st = conn.createStatement();

// Turn use of the cursor on.
st.setFetchSize(50);
Run Code Online (Sandbox Code Playgroud)

Ant*_*sma 4

psycopg2 dbapi 驱动程序在返回任何行之前缓冲整个查询结果。您需要使用服务器端游标来增量获取结果。对于 SQLAlchemy,请参阅文档中的 server_side_cursors,如果您使用 ORM,请参阅Query.yield_per() 方法

SQLAlchemy 目前没有为每个查询设置该选项的选项,但有一个带有用于实现该查询的补丁的票证