이것은 매우 기본적인 질문처럼 보일 수 있으며 실제로 그렇습니다. 그러나 과학적 방법의 팬으로서 나는 가설을 만들고 테스트하여 내가 맞는지 테스트합니다. 이 경우, sys.dm_exec_sessions
보다 구체적으로 단일 열 "읽기" 의 출력을 더 잘 이해하려고합니다 .
SQL Server 온라인 설명서에서는이를 다음과 같이 건조하게 지정합니다.
이 세션 동안이 세션의 요청에 의해 수행 된 읽기 수 널 입력 가능하지 않습니다.
세션 시작 이후이 세션이 발행 한 요청을 충족시키기 위해 디스크에서 읽은 페이지 수를 표시한다고 가정 할 수 있습니다 . 이것이 제가 테스트 할 것이라고 생각한 가설입니다.
logical_reads
같은 테이블 의 열은 다음과 같이 정의됩니다.
세션에서 수행 된 논리적 읽기 수입니다. 널 입력 가능하지 않습니다.
SQL Server 사용 경험을 바탕으로이 열 은 디스크 와 메모리 에서 읽은 페이지 수를 반영한다고 생각합니다 . 즉, 총 페이지 수는 적 세션, 해당 페이지가 존재 상관없이 읽을. 비슷한 정보를 제공하는 두 개의 별도 열을 갖는 차별화 요소 또는 가치 제안 은 특정 세션에 대해 디스크에서 읽은 페이지 와 버퍼 캐시에서 읽은 페이지의 비율을 이해할 수있는 것으로 보입니다 .reads
logical_reads
테스트 장비에서 새 데이터베이스를 만들고 알려진 페이지 수의 데이터로 단일 테이블을 만든 다음 새 세션에서 해당 테이블을 읽습니다. 그런 다음 세션에 대해 및 열의 sys.dm_exec_sessions
내용을 확인했습니다 . 이 시점에서 나는 결과에 혼란스러워한다. 아마 여기 누군가가 나를 위해 이것에 대해 약간의 빛을 비출 수 있습니다.reads
logical_reads
시험 장비 :
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;
위의 첫 번째 select 문은 실제로 테이블이 10,000 개의 행으로 구성되어 있으며 총 페이지 5,025 개, 사용 된 페이지 5,020 개 및 데이터 페이지 5,000 개로 구성되어 있습니다. 정확하게 예상대로 :
두 번째 select 문은 TestReads
테이블에 대한 메모리가 없음을 확인 합니다.
A의 새로운 세션 , 우리는 SESSION_ID의 메모를 복용, 다음 쿼리를 수행합니다
USE TestReads;
SET STATISTICS IO ON;
SELECT *
FROM dbo.TestReads;
다음과 같이 출력에서 볼 수 있듯이 디스크에서 메모리로 전체 테이블을 읽습니다 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.
A의 세 번째 세션, 우리는 검사 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 */
과에 대해 5,000 회 이상sys.dm_exec_sessions
표시 될 것으로 예상됩니다 . 아아, 나는 0을 보여준다. 5,000의 북쪽 어딘가에 예상되는 읽기 수를 보여줍니다-내 테스트에서 5,020을 보여줍니다.reads
logical_reads
reads
logical_reads
DMV TestReads
덕분에 SQL Server가 전체 테이블을 메모리로 읽은 것을 알고 있습니다 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;
내가 무엇을 잘못하고 있지?
이 테스트에는 SQL Server 2012 11.0.5343을 사용하고 있습니다.
추가 결과 :
내가 다음을 실행하면 :
SELECT des.session_id
, des.reads
, des.logical_reads
FROM sys.dm_exec_sessions des
reads
테스트 리그를 생성하는 세션에서 784를 보았습니다 . 그러나 다른 모든 세션은 reads
열에 0으로 표시 됩니다.
이제 SQL Server 테스트 인스턴스를 11.0.6020으로 업데이트했습니다. 그러나 결과는 같습니다.
SET STATISTICS IO ON
두 번째 세션의 표에서 읽기 직전에 흥미로운 것은 3 개의 물리적 읽기와 4998 개의 미리 읽기를 나타냅니다. 그러나 sys.dm_exec_sessions
여전히 reads
열에 반영하지 않습니다 .
STATISTICS IO
i.stack.imgur.com/XbHae.png
reads
필드 의 증가에 약간의 지연을 보았습니다 . "요청"이 끝날 때까지 증가하지 않는 세션 당 tempdb 사용량을 나타내는 session_space_usage 또는 다른 DMV와 매우 유사하게 작동합니다.
sys.dm_exec_requests
set statistics io on
결과 와 거의 동일 합니다.