Jer*_*hka 20 sql-server execution-plan
SQL Server 图形执行计划从右到左从上到下读取。生成的输出是否有有意义的顺序SET STATISTICS IO ON?
以下查询:
SET STATISTICS IO ON;
SELECT *
FROM Sales.SalesOrderHeader AS soh
JOIN Sales.SalesOrderDetail AS sod ON soh.SalesOrderID = sod.SalesOrderID
JOIN Production.Product AS p ON sod.ProductID = p.ProductID;
Run Code Online (Sandbox Code Playgroud)
生成这个计划:

这个STATISTICS IO输出:
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'SalesOrderDetail'. Scan count 1, logical reads 1246, physical reads 3, read-ahead reads 1277, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'SalesOrderHeader'. Scan count 1, logical reads 689, physical reads 1, read-ahead reads 685, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Product'. Scan count 1, logical reads 15, physical reads 1, read-ahead reads 14, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Run Code Online (Sandbox Code Playgroud)
所以,我重申:什么给了?是否有有意义的STATISTICS IO输出顺序或使用了一些任意顺序?
我最初玩弄各种查询表明根本没有模式,但仔细观察它似乎可以预测串行计划。我结束了在KB314648其中@AustinZellner提到:
每个 SQL Server 连接都有一个关联的进程状态结构 (PSS),用于维护特定于连接的状态信息。sysprocesses 系统表中的每个唯一服务器进程 ID (SPID) 代表一个不同的 PSS,而 sysprocesses 虚拟表中的信息是此状态信息的“视图”。
以及与您的问题相关的部分:
如果为连接启用了 STATISTICS IO,SQL Server 会在查询执行期间分配一个数组,以跟踪每个表的 IO 信息。当 SQL Server 处理查询时,它会在此数组中相应表的条目中记录对页面的每个逻辑请求,以及该逻辑 IO 请求是否导致物理 IO。SQL Server 在查询结束时返回错误消息 3615 中的信息。
观察到的行为表明,按 IO 生成的顺序对数组进行条目,本质上是物理运算符上 GetNext() 的结果。统计输出中的最后一个条目是导致记录 IO 的第一个表,第一个条目是最后一个表。我推测并行计划的顺序是不可预测的(或更少),因为无法保证首先安排哪个并行任务。
在我看来,这与计划中的数据读取访问顺序相反。您的计划将首先从 Product 表中读取以构建哈希表(工作表)。然后它从 SalesOrderHeader 中读取并形成 SalesOrderDetail 将它们与合并连接运算符相结合。然后从最后读取工作表以将原始 Product 行与来自合并连接的行进行哈希匹配。这与它们在统计输出中列出的顺序完全相反。
但是,我不知道有任何文件可以说明这一点。如果您想确定表访问发生的顺序,请阅读执行计划。
我一直认为它有一个顺序,从那时起我做的编程多于管理。我仔细检查了一些执行计划并仔细检查了我的信念。
这是我所看到的:
在多步骤查询(例如我们的许多存储过程)中,顺序反映了查询运行的物理顺序。
对于特定的查询,统计信息 IO 似乎通过报告从右侧开始并向左进行的统计信息来反映执行计划
也许这更多的是一种观察。