web-dev-qa-db-fra.com

Les statistiques =IO SORTIE incluent-elles les lectures de la version?

SQL Server a une option SET STATISTICS IO ON qui montre le nombre de lectures de page logique et physique pour une requête. Ces statistiques comprennent-elles les lectures de la version de la version pour les requêtes d'instantané et de RCSI?

9
Forrest

STATISTICS IO n'inclut pas les lectures de la version de version, au moins pour la version de la version dans TEMPDB.

Voici une démo pour la 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 30S 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 tandis que la boucle va, courez deux requêtes identiques dans SNAPSHOT avec STATISTICS IO ON, séparé par 15s pour permettre aux versions d'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 IO statistiques montrent des lectures identiques: -Stats IO

Mais le plan d'exécution réel indique la numérisation de la deuxième requête prenant beaucoup plus de temps, en raison de la lecture de la version de la version. Actual plans

Pour vous prouver que cette requête a abouti à TEMPDB lit, vous pouvez utiliser cette session d'événements étendue (qui est évidemment meilleure que le profileur), filtrée à la session où les requêtes de lecture sont en cours d'exécution:

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

Affichage des "données en direct" pour cette session XE pendant la démonstration, vous pouvez voir des lectures sur la base de données ID 2 (TEMPDB) et capture le texte de la requête de notre requête de lecture également:

screenshot of XE session showing tempdb reads

Spécial grâce à Paul White pour avoir présenté ce problème avec des statistiques IO.

10
Forrest