【问题标题】:When does a SELECT query begin to return rows?SELECT 查询何时开始返回行?
【发布时间】:2013-08-05 10:15:58
【问题描述】:

假设以下查询:

SELECT * FROM table;

DBMS 会在获取第一行后立即给我还是先获取所有行(将它们保存在某种缓冲区中)然后一次给我所有行?

如果我的问题不清楚。假设table 中的行数使得 DBMS 将花费 60 分钟来获取所有行。 DBMS 会在 60 分钟内逐步返回行,还是我必须等待 60 分钟才能收到任何数据?

【问题讨论】:

  • 嗯...有趣。您的测试表明了什么?
  • @AndrewMorton 我的测试表明它使用了某种缓存。另外,我相信使用缓存方法处理事务会更容易。但是,到目前为止,我只用psql 进行了测试,所以我不知道这种行为是由于psql 还是由于dbms。
  • psql 的行为与典型的简单应用程序相同。它基于 libpq,所以 libpq 在客户端收集内存中的所有数据,当查询完成后,将控制权返回给客户端。您可以通过将 FETCH_COUNT 设置为 1000(获取 1000 行后返回给客户端)重新定义它以使用游标 - \set FETCH_COUNT 1000
  • 在查询继续搜索时,如果有一个除 FIRST ROWS 指令之外的选项来立即预览部分结果,那肯定会很好。尤其是当用户知道查询可能只从大表中返回很少的结果时!请参阅我的相关@​​987654321@。

标签: sql postgresql select


【解决方案1】:

视情况而定。

例如,Oracle 数据库默认会优化吞吐量并尝试返回所有行,或者您可以使用 `/*+ FIRST_ROWS( n) */ optimizer hint.

至于 PostgresSQL,它没有优化器提示(参见 thesetwo 链接)。我可以假设默认情况下它会尝试优化吞吐量。

【讨论】:

  • PostgreSQL 不为此目的使用提示,但是当您使用游标时,查询会针对快速的前 10% 行进行优化(cursor_tuple_fraction 的默认值)。
【解决方案2】:

这里没有硬性规定。但在实践中,数据库引擎应该更愿意在行可用时立即返回。效率优势大而明显。

请注意,并非所有查询都可以这样做。一个非常常见的例子是没有支持索引的order by 子句。为了排序,数据库必须创建已排序表的服务器端副本。这意味着在排序操作完成之前它不能开始返回行。

【讨论】:

    【解决方案3】:

    在 PostgreSQL 中,如果查询执行计划允许,服务器确实会在行可用时立即将它们返回给客户端。在您的简单示例中就是这种情况。在其他情况下,例如,如果您可能在最后进行排序,并且必须等待其完成。

    但是如果你使用标准的 libpq 接口,客户端库会在将整个结果返回给客户端程序之前在内存中构建整个结果。要逐行获取结果,需要在 libpq 中使用single-row mode。如果您使用其他界面或其他语言,结果可能会有所不同。

    【讨论】:

    • 您知道9.2之前的任何解决方案吗?
    • 使用服务器端光标。
    【解决方案4】:

    大多数(如果不是全部)基于 SQL 的服务器在查询完成搜索之前不允许您查看任何行。一些服务器提供了 FIRST ROWS 指令(提示),以便服务器更快地提供第一组行。有关此主题的更多信息,请参阅我的相关@​​987654321@。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-07
      • 1970-01-01
      相关资源
      最近更新 更多