【问题标题】:Does SQL Server always physically build the full result set?SQL Server 是否总是在物理上构建完整的结果集?
【发布时间】:2017-02-07 14:12:32
【问题描述】:

假设我有一个包含 20 列和十亿行数据的大表。然后我运行一个简单的查询,例如:

select [First Name], [Last Name]
from Audience;

之后我依次读取结果集。 SQL Server 会在我开始读取结果集之前在服务器端物理创建所有记录(即十亿条记录)吗?是否有任何查询计划可以在将结果集提供给客户端的同时动态构建结果集?

我知道并发原因可能会阻止这种情况。我可以提示无法进行多用户访问吗?也许我应该使用游标?

【问题讨论】:

  • 数据库将使用游标和可能存在的任何索引遍历表中已经存在的记录。您是否建议 SQL Server 实际上为读取目的制作数据库副本?
  • 是的,我的问题是我如何猜测(当使用像上面这样的简单查询时)服务器何时会复制数据以用于读取目的,何时不会?
  • 对于简单的情况,不要考虑这个,想想你的查询策略有多高效。在某些情况下,数据库会正式复制记录,例如在锁定更新期间,但对于简单的SELECT,您无需担心这一点。
  • @Buran,一旦执行计划中的最后一个阻塞操作符完成(例如SORT),结果将被流式传输到客户端。像您的示例这样的简单查询可能仅包含 SELECTSCAN,因此将立即返回结果,无需中间存储或处理。

标签: sql-server


【解决方案1】:

取决于查询计划。如果查询不需要任何临时内部结构,那么是的,即使在构建完整记录集之前,您也会立即得到响应。如果查询确实需要临时内部存储(例如,您以与任何索引都不匹配的方式对其进行排序,或者索引可用但使用了不同的索引,因为它需要较少的 I/O),那么您将不得不等待直到构建完整的记录集。

唯一的判断方法是查看查询计划并检查每一步。您将需要知道如何解释它们……例如,DISTINCT 将需要一个临时结构,而FLOW DISTINCT 则不需要。如果查询计划显示EAGER SPOOL,您肯定需要等待,尽管there are a few things you can do 可以避免它们。

注意:您不能依赖这一点 - 查询计划不仅会根据架构或索引,还会根据数据库统计信息(例如选择性)而变化,这些统计信息总是在变化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-23
    • 1970-01-01
    • 2013-03-27
    • 2021-10-13
    • 1970-01-01
    相关资源
    最近更新 更多