Bu çok temel bir soru gibi görünebilir ve gerçekten de olması gerekir. Ancak, bilimsel yöntemin bir hayranı olarak, bir hipotez oluşturmayı, sonra doğru olup olmadığımı görmek için test etmeyi seviyorum. Bu durumda, daha iyi sys.dm_exec_sessions
tek sütun "okur" çıktısını daha iyi anlamaya çalışıyorum .
SQL Server Books Online'da bunu oldukça kuru olarak belirtilir:
Bu oturumdaki isteklere göre, bu oturum sırasında gerçekleştirilen okuma sayısı. Null değeri yoktur.
Bunun , oturumun başlamasından bu yana bu oturum tarafından yayınlanan istekleri karşılamak için diskten okunan sayfa sayısını göstereceği varsayılabilir . Test edeceğimi düşündüğüm hipotez bu.
logical_reads
Aynı tabloda, kolon gibi tanımlanır:
Oturumda gerçekleştirilen mantıksal okuma sayısı. Null değeri yoktur.
SQL Server kullanma deneyiminden, bu sütunun hem diskten hem de bellekten okunan sayfa sayısını yansıttığına inanıyorum . Başka bir deyişle, toplam sayfa sayısı hiç oturumda, bu sayfalar ikamet olursa olsun tarafından okunan. Benzer bilgiler sunan iki ayrı sütuna sahip olmanın farklılaştırıcısı veya değer önerisi, belirli bir oturum için diskten ( ) okunan sayfaların arabellek önbelleğinden ( ) okunan sayfalara oranını anlayabilecek gibi görünmektedir .reads
logical_reads
Test cihazımda yeni bir veritabanı oluşturdum, bilinen sayıda sayfa içeren tek bir tablo oluşturdum ve sonra bu tabloyu yeni bir oturumda okudum. Sonra oturumu hakkında ve sütunlar sys.dm_exec_sessions
ne dedi görmek için baktım . Bu noktada sonuçlardan şaşkınım. Belki buradaki biri benim için buna biraz ışık tutabilir.reads
logical_reads
Test düzeneği:
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;
Yukarıdaki ilk select deyimi aslında tablonun toplamda 5.025 sayfa, 5.020 kullanılmış sayfa ve 5.000 veri sayfası içeren 10.000 satırdan oluştuğunu; tam olarak beklendiği gibi:
İkinci select deyimi TestReads
tablo için bellekte hiçbir şey olmadığını doğrular .
Bir de yeni oturum , biz session_id dikkat ederek, aşağıdaki sorguyu yapın:
USE TestReads;
SET STATISTICS IO ON;
SELECT *
FROM dbo.TestReads;
Beklendiği gibi, bu tüm tabloyu çıktıdaki gibi diskten belleğe okur 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.
Bir de üçüncü oturumda, biz incelemek 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 */
Ben ve her ikisi için en az 5.000 sys.dm_exec_sessions
gösteri görmek beklenir . Ne yazık ki, sıfır gösterir. 5.000'in kuzeyinde bir yerde beklenen sayıda okuma gösteriyor - testimde 5.020 gösteriyor:reads
logical_reads
reads
logical_reads
SQL Server DMV TestReads
sayesinde tüm tabloyu belleğe okuduğunu biliyorum sys_dm_os_buffer_descriptors
:
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;
Neyi yanlış yapıyorum?
Bu test için SQL Server 2012 11.0.5343 kullanıyorum.
Diğer bulgular:
Aşağıdakileri çalıştırırsam:
SELECT des.session_id
, des.reads
, des.logical_reads
FROM sys.dm_exec_sessions des
reads
Test donanımını oluşturduğum oturumda 784'ü görüyorum ; ancak diğer tüm oturumlar reads
sütunda sıfır gösterir .
Şimdi SQL Server test örneğimi 11.0.6020 olarak güncelledim; ancak sonuç aynıdır.
SET STATISTICS IO ON
2. oturumdaki tablodan okumadan hemen önce ilginç olan 3 fiziksel okuma ve 4998 önceden okuma raporları; ancak sys.dm_exec_sessions
yine de reads
sütunda bunu yansıtmaz .
STATISTICS IO
i.stack.imgur.com/XbHae.png adresinden
reads
Alanların bazı artışlarında da bir gecikme görüyorum . Ben çok session_space_usage veya "istek" bitene kadar artmaz oturum başına tempdb kullanımını gösteren herhangi bir DMV gibi çalışır şüpheli.
sys.dm_exec_requests
set statistics io on
sonuçlarla hemen hemen aynı olacaktır .