La sortie STATISTICS IO inclut-elle les lectures du magasin de versions?

9

SQL Server dispose d'une option SET STATISTICS IO ONqui affiche le nombre de lectures de pages logiques et physiques pour une requête. Ces statistiques incluent-elles les lectures du magasin de versions pour les requêtes SNAPSHOT et RCSI?

Forrest
la source

Réponses:

10

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 SNAPSHOTavec 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: Stats IO

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. Plans réels

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:

capture d'écran de la session XE montrant les lectures de tempdb

Un merci spécial à Paul White pour avoir soulevé ce problème avec STATISTICS IO.

Forrest
la source