STATISTICS IO
n'inclut pas les lectures du magasin de versions, du moins pour le magasin de versions dans tempdb.
Voici une démo pour preuve:
--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
Démarrer une boucle de mise à jour des années 30 dans un onglet SSMS
--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
Et pendant la boucle, exécutez deux requêtes identiques SNAPSHOT
avec STATISTICS IO ON
, séparées par 15 secondes pour permettre aux versions de s'accumuler.
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
Les statistiques IO montrent des lectures identiques:
Mais le plan d'exécution réel montre que l'analyse de la deuxième requête prend beaucoup plus de temps, en raison de la lecture du magasin de versions.
Pour vous prouver que cette requête a abouti à des lectures tempdb, vous pouvez utiliser cette session Extended Events (qui est évidemment meilleure que Profiler), filtrée sur la session où s'exécutent les requêtes de lecture:
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
En affichant les "données en direct" de cette session XE pendant la démo, vous pouvez voir les lectures par rapport à l'ID de base de données 2 (tempdb), et il capture également le texte de la requête de notre requête en lecture:
Un merci spécial à Paul White pour avoir soulevé ce problème avec STATISTICS IO.