以下查询立即返回数据:
SELECT time, value from data order by time limit 100;
如果没有limit子句,服务器开始返回行需要很长时间:
SELECT time, value from data order by time;
我通过使用查询工具(psql
)和使用API查询来观察这一点。
问题/问题:
setFetchSize
是解决这个问题的关键。在我的例子中,我使用SQLAlchemy从python执行查询。 如何为单个查询设置该选项(由session.execute
执行)?我使用psycopg2驱动程序。列time
是主键,BTW。
修改
我相信JDBC driver documentation中的这段摘录描述了问题并提示了一个解决方案(我仍然需要帮助 - 请参阅上面的最后一个项目符号列表项目):
默认情况下,驱动程序会立即收集查询的所有结果。这对于大型数据集来说可能不方便,因此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);
答案 0 :(得分:4)
psycopg2 dbapi驱动程序在返回任何行之前缓冲整个查询结果。您需要使用服务器端游标来逐步获取结果。对于SQLAlchemy,请参阅server_side_cursors in the docs,如果您正在使用ORM Query.yield_per() method。
SQLAlchemy目前没有为每个查询设置的选项,只有there is a ticket with a patch for implementing that。
答案 1 :(得分:0)
理论上,因为你的ORDER BY是主键,所以不需要一些结果,而DB确实可以按关键顺序立即返回数据。
我希望有能力的数据库注意到这一点,并对其进行优化。似乎PGSQL不是。 *耸肩*
如果您有LIMIT 100,则不会发现任何影响,因为它可以非常快速地将这100个结果从数据库中提取出来,如果它们在发货之前首先收集并排序,您将不会发现任何延迟给你的客户。
我建议尝试删除ORDER BY。很可能,你的结果会按时间正确排序(考虑到你的PK,甚至可能有一个标准或规范要求这样做),你可能会更快地得到你的结果。