Answers:
STATISTICS IO
不包括版本存储读取,至少对于tempdb中的版本存储而言。
这是一个演示示例:
--setup script
USE master
GO
CREATE DATABASE TestDB
GO
ALTER DATABASE TestDB
SET ALLOW_SNAPSHOT_ISOLATION ON
GO
USE TestDB
GO
DROP TABLE IF EXISTS dbo.Test
GO
CREATE TABLE dbo.Test (ID int identity PRIMARY KEY, junk int)
INSERT dbo.Test
SELECT TOP (100000) 1
FROM master.dbo.spt_values a
CROSS JOIN master.dbo.spt_values b
在一个SSMS标签中启动30秒更新循环
--UPDATE loop
SET NOCOUNT ON
DECLARE @stop datetime = DATEADD(SECOND, 30, GETDATE())
WHILE GETDATE() < @stop
BEGIN
BEGIN TRAN
UPDATE dbo.Test
SET junk += 1
COMMIT
END
UPDATE dbo.Test
SET junk = 1
并且在循环进行时,请使用来运行两个相同的查询,SNAPSHOT
并STATISTICS IO ON
用15s隔开,以允许版本累积。
USE TestDB
SET STATISTICS IO ON
GO
SET TRANSACTION ISOLATION LEVEL SNAPSHOT
BEGIN TRAN
SELECT MAX(junk)
FROM dbo.Test
WAITFOR DELAY '00:00:15'
SELECT MAX(junk)
FROM dbo.Test
COMMIT
但是由于读取版本存储,实际的执行计划显示对第二个查询的扫描要花费更多的时间。
为了向自己证明此查询导致了tempdb读取,可以使用此扩展事件会话(显然比Profiler更好),并过滤到运行读取查询的会话:
CREATE EVENT SESSION [file_reads] ON SERVER
ADD EVENT sqlserver.file_read_completed(
ACTION(sqlserver.session_id,sqlserver.sql_text)
WHERE ([sqlserver].[session_id]=(52)))
ADD TARGET package0.event_file(SET filename=N'file_reads')
GO
在演示过程中查看该XE会话的“实时数据”,您可以看到对数据库ID 2(tempdb)的读取,并且还捕获了我们的读取查询的查询文本:
特别感谢Paul White向STATISTICS IO提出了这个问题。