有人能够解释我在 SQL Profiler 中看到的一些行为吗?取以下两批:
exec sp_executesql N'
declare @t table (
x int
)
insert into @t (x) select top 10 number from dbo.gennumbers
select * from @t
union
select * from @t
'
exec sp_executesql N'
select top 10 number from dbo.gennumbers
union
select top 10 number from dbo.gennumbers
'
(这是我正在做的一些重构的简化;实际上,临时表是通过在最终查询中重用的 CTE 填充的,因此通过缓存数据来减少 SQL Server 需要做的重复工作量)。
在此示例中,GenNumbers 只是一个数字表,其中包含仅包含连续数字的单列 - 没什么特别的。
在探查器中,我得到以下结果:
第 1 批,使用临时表:
事件 TextData 读取 SP:StmtCompleted INSERT INTO(...) 27 SP:StmtCompleted SELECT * FROM ... 6 SQL:StmtCompleted exec sp_executesql 170
Batch 2,直接命中:
事件 TextData 读取 SP:StmtCompleted SELECT TOP 10 * ... 6 SQL:StmtCompleted exec sp_executesql 6
我试图理解的是SQL:StmtCompleted
. 我期望总读取应该等于批次中发生的所有读取的总和,但是在批次 1 中似乎并非如此 - 事实上,它要高得多。而第 2 批执行单次选择,最终读取 == 实际读取。
执行计划中没有什么明显的东西可以查看额外时间的去向,但也许我没有捕捉到正确的东西 - 有人对实际发生的事情有任何想法吗?我想知道我是否需要担心 SQL Server “给”我额外的 100 次读取,因为这个读取计数是实际读取计数的五到六倍。
我假设这与需要维护有关临时表的信息的 SQL 有关,但不清楚究竟是什么。任何灯棚都是有用的。
当表超出与 the或语句无关的范围
CREATE TABLE
时,开头和结尾都有一个隐式。DROP TABLE @T
INSERT
SELECT
如果您替换为
#temp
表格,您应该会看到对drop
andcreate
语句的一些额外读取。对我来说,我看到 36 个CREATE
和 100 个,DROP
因此占您丢失的 137 个读数中的 136 个。#temp
(带表格的脚本)