Cela peut sembler une question très fondamentale, et ça devrait l'être. Cependant, en tant que fan de la méthode scientifique, j'aime créer une hypothèse, puis la tester pour voir si j'ai raison. Dans ce cas, j'essaie de mieux comprendre la sortie sys.dm_exec_sessions, et plus précisément, la colonne unique "lit".
La documentation en ligne de SQL Server spécifie plutôt sèchement ceci:
Nombre de lectures effectuées, par requêtes dans cette session, au cours de cette session. N'est pas annulable.
On pourrait supposer que cela indiquerait le nombre de pages lues sur le disque pour satisfaire les demandes émises par cette session depuis le début de la session. C'est l'hypothèse que je pensais tester.
La logical_readscolonne de cette même table est définie comme suit:
Nombre de lectures logiques effectuées sur la session. N'est pas annulable.
D'après mon expérience avec SQL Server, je pense que cette colonne reflète le nombre de pages qui ont été lues à la fois sur le disque et en mémoire . En d' autres termes, le nombre total de pages jamais lu par la session, peu importe où ces pages résident. Le différenciateur, ou proposition de valeur, d'avoir deux colonnes distinctes qui offrent des informations similaires semble être que l'on peut comprendre le rapport entre les pages lues sur le disque ( reads) et celles lues dans le cache de tampon ( logical_reads) pour une session spécifique.
Sur mon banc de test, j'ai créé une nouvelle base de données, créé une seule table avec un nombre connu de pages de données, puis lu cette table dans une nouvelle session. Ensuite, j'ai regardé sys.dm_exec_sessionspour voir ce que les colonnes readset ont logical_readsdit sur la session. À ce stade, je suis confus par les résultats. Peut-être que quelqu'un ici peut faire la lumière à ce sujet pour moi.
Le banc d'essai:
USE master;
IF EXISTS (SELECT 1
    FROM sys.databases d 
    WHERE d.name = 'TestReads')
BEGIN
    ALTER DATABASE TestReads SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    DROP DATABASE TestReads;
END
GO
CREATE DATABASE TestReads;
GO
ALTER DATABASE TestReads SET RECOVERY SIMPLE;
BACKUP DATABASE TestReads TO DISK = 'NUL:'; /* ensure we are in 
                                            simple recovery model */
GO
USE TestReads;
GO
/*
    create a table with 2 rows per page, for easy math!
*/
CREATE TABLE dbo.TestReads
(
    ID INT NOT NULL
        CONSTRAINT PK_TestReads
        PRIMARY KEY CLUSTERED
        IDENTITY(1,1)
    , SomeData CHAR(4000) NOT NULL
);
/*
    insert 5000 pages of data
*/
INSERT INTO dbo.TestReads (SomeData)
SELECT TOP(10000) o1.name
FROM sys.objects o1
    , sys.objects o2
    , sys.objects o3
ORDER BY o1.object_id
    , o2.object_id
    , o3.object_id;
/*
    Verify we have 5,000 pages of data, with 10,000 rows.
*/
SELECT o.name
    , p.rows
    , au.total_pages
    , au.used_pages
    , au.data_pages
FROM sys.partitions p
    INNER JOIN sys.objects o ON p.object_id = o.object_id 
    INNER JOIN sys.allocation_units au 
        ON p.hobt_id = au.container_id 
        AND (au.type = 1 or au.type = 0)
WHERE p.index_id = 1
    AND o.name = 'TestReads'
    AND o.type = 'U';
/*
    issue a checkpoint to ensure dirty pages are flushed to disk
*/
CHECKPOINT 30;
DBCC DROPCLEANBUFFERS;
DBCC FREESYSTEMCACHE ('ALL');
DBCC FREEPROCCACHE;
DBCC FREESESSIONCACHE;
GO
/*
    ensure we have no data cached in memory for the TestReads database
*/
USE master;
ALTER DATABASE TestReads SET OFFLINE WITH ROLLBACK IMMEDIATE;
ALTER DATABASE TestReads SET ONLINE;
SELECT DatabaseName = d.name
    , SchemaName = s.name
    , ObjectName = o.name
    , AllocatedMB = COUNT(1) * 8192E0 / 1048576
    , PagesInMemory = COUNT(1)
FROM sys.dm_os_buffer_descriptors dobd
    INNER JOIN sys.allocation_units au 
        ON dobd.allocation_unit_id = au.allocation_unit_id
    INNER JOIN sys.partitions p 
        ON au.container_id = p.hobt_id 
             AND (au.type = 1 OR au.type = 0)
    INNER JOIN sys.objects o ON p.object_id = o.object_id
    INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
    INNER JOIN sys.databases d 
        ON dobd.database_id = d.database_id
WHERE d.name = 'TestReads'
    AND o.name = 'TestReads'
    AND o.type = 'U'
GROUP BY d.name
    , s.name
    , o.name;
Le premier énoncé de sélection ci-dessus montre qu'en fait, le tableau comprend 10 000 lignes, avec 5 025 pages au total, 5 020 pages utilisées et 5 000 pages de données; exactement comme on pourrait s'y attendre:
La deuxième instruction select confirme que nous n'avons rien en mémoire pour la TestReadstable.
Dans une nouvelle session , nous effectuons la requête suivante, en prenant note de la session_id:
USE TestReads;
SET STATISTICS IO ON;
SELECT *
FROM dbo.TestReads;
Comme on pouvait s'y attendre, cela lit la table entière du disque dans la mémoire, comme indiqué dans la sortie de SET STATISTICS IO ON:
(10000 row(s) affected)
Table 'TestReads'. Scan count 1, logical reads 5020, physical reads 3, 
read-ahead reads 4998, lob logical reads 0, lob physical reads 0, lob 
read-ahead reads 0.
Dans une troisième session, nous inspectons sys.dm_exec_sessions:
SELECT des.session_id
    , des.reads
    , des.logical_reads
FROM sys.dm_exec_sessions des
WHERE des.session_id = 57; /* session_id from the 2nd (previous) session */
Je m'attends à voir au moins 5 000 sys.dm_exec_sessionsspectacles pour et . Hélas, je vois montre zéro.  montre un nombre attendu de lectures quelque part au nord de 5 000 - il montre 5 020 dans mon test:readslogical_readsreadslogical_reads
Je sais que SQL Server a lu la TestReadstable entière en mémoire, grâce au sys_dm_os_buffer_descriptorsDMV:
USE TestReads;
GO
SELECT DatabaseName = d.name
    , SchemaName = s.name
    , ObjectName = o.name
    , AllocatedMB = COUNT(1) * 8192E0 / 1048576
    , PagesInMemory = COUNT(1)
FROM sys.dm_os_buffer_descriptors dobd
    INNER JOIN sys.allocation_units au 
        ON dobd.allocation_unit_id = au.allocation_unit_id
    INNER JOIN sys.partitions p 
        ON au.container_id = p.hobt_id 
            AND (au.type = 1 OR au.type = 0)
    INNER JOIN sys.objects o ON p.object_id = o.object_id
    INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
    INNER JOIN sys.databases d 
        ON dobd.database_id = d.database_id
WHERE d.name = 'TestReads'
    AND o.name = 'TestReads'
    AND o.type = 'U'
GROUP BY d.name
    , s.name
    , o.name;
Qu'est-ce que je fais mal?
J'utilise SQL Server 2012 11.0.5343 pour ce test.
Autres constatations:
Si je lance ce qui suit:
SELECT des.session_id
    , des.reads
    , des.logical_reads
FROM sys.dm_exec_sessions des
Je vois reads784 dans la session où je crée le banc d'essai; cependant, toutes les autres sessions affichent zéro dans la readscolonne.
J'ai maintenant mis à jour mon instance de test SQL Server vers 11.0.6020; cependant le résultat est le même.
SET STATISTICS IO ONjuste avant de lire le tableau de la 2e session rapporte 3 lectures physiques et 4998 lectures anticipées; mais sys.dm_exec_sessionsne reflète toujours pas cela dans la readscolonne.
                STATISTICS IO i.stack.imgur.com/XbHae.png
                readschamps. Je soupçonne que cela fonctionne un peu comme session_space_usage ou tout autre DMV qui montre l'utilisation de tempdb par session qui n'augmente pas jusqu'à la fin de la "demande".
                


sys.dm_exec_requestsvous donnera presque les mêmesset statistics io onrésultats.