For*_*est 9 sql-server tempdb-version-store
SQL Server 有一个选项SET STATISTICS IO ON
可以显示查询的逻辑和物理页读取次数。这些统计信息是否包括 SNAPSHOT 和 RCSI 查询的版本存储读取?
For*_*est 10
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
Run Code Online (Sandbox Code Playgroud)
在一个 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
Run Code Online (Sandbox Code Playgroud)
在循环进行时,在SNAPSHOT
with 中运行两个相同的查询STATISTICS IO ON
,间隔 15 秒以允许版本累积。
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
Run Code Online (Sandbox Code Playgroud)
但实际执行计划显示,由于读取版本存储,第二个查询的扫描花费了更多时间。
为了向自己证明这个查询导致了 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
Run Code Online (Sandbox Code Playgroud)
在演示期间查看该 XE 会话的“实时数据”,您可以看到针对数据库 id 2 (tempdb) 的读取,它也捕获了我们读取查询的查询文本:
特别感谢 Paul White 向 STATISTICS IO 提出这个问题。
归档时间: |
|
查看次数: |
225 次 |
最近记录: |