セージ の メモ書き

メモこそ命の恩人だ

SQL Server - 先行読み取り (Read Ahead)

先行読み取り (Read Ahead)

ページの読み取り - SQL Server | Microsoft Docs

  • クエリの実行前に、予想したページをバッファキャッシュに取得する機能。
    • 連続したページを読み取る。(最大64ページ)
    • 10万ページ以上の先行読み取りを確認。仕様通り? 後述参照。
    • 断片化すると連続ページにならない。その領域は、先行読み取りの効果が薄い。
  • 予想対象のページタイプは以下の2つ。
    • データページ
    • インデックスページ
  • 予想方法
    • 不明...
    • 統計情報などを使ってる???

先行読み取りしたページ数の確認

SET STATISTICS IO (Transact-SQL) - SQL Server | Microsoft Docs

  • SET STATISTICS IO コマンドで把握できる。
  • Azure SQL Database では使用できなかった。

一部、抜粋

項目 内容
スキャン数 リーフレベル到達後、任意の方向にシークした数
論理読み取り数 バッファキャッシュの参照ページ数
物理読み取り数 ストレージの参照ページ数
先読みの読み取り数 先行読み取りしたページ数
USE SampleDb;
--CREATE TABLE SampleTable1 (Id int PRIMARY KEY, Data1 char (5000));  
TRUNCATE TABLE SampleTable1;
GO

-- データ登録(100,000 ページ分)
DECLARE @Count INT = 1;
WHILE @Count <= 100000 BEGIN
    INSERT INTO SampleTable1 (Id, Data1) VALUES (@Count, 0x01);
    SET @Count += 1;
END

-- キャッシュクリア
CHECKPOINT;
DBCC DROPCLEANBUFFERS;
GO

-- ページ数+処理時間の表示
SET STATISTICS IO ON;
SET STATISTICS TIME ON;

-- 【1回目】
SELECT * FROM SampleTable1;
-- スキャン数 1、論理読み取り数 100373、物理読み取り数 3、先読みの読み取り数 100369
-- CPU 時間 = 594 ミリ秒、経過時間 = 3373 ミリ秒

-- 【2回目】
SELECT * FROM SampleTable1;
-- スキャン数 1、論理読み取り数 100373、物理読み取り数 0、先読みの読み取り数 0
-- CPU 時間 = 421 ミリ秒、経過時間 = 2917 ミリ秒。

-- 設定解除
SET STATISTICS TIME OFF;
SET STATISTICS IO OFF;
  • 結果(1回目のクエリ)
    • 100369 ページの先行読み取りが動作したことを確認。
    • その結果、物理読み取り数が 3ページになった。
    • 先行読み取りも、IOアクセスするので、物理読み取りみたいなものだが。。。
  • 結果(2回目のクエリ)
    • バッファキャッシュにあるので、先行読み取りが 0 になったことを確認。
    • 論理読み取り数のみが 100373。
SELECT 
    DB_NAME(dobd.database_id), 
    OBJECT_NAME(ddpi.object_id), 
    dobd.page_type,
    COUNT(*)
FROM sys.dm_os_buffer_descriptors as dobd
CROSS APPLY sys.dm_db_page_info (DB_ID(), 1, dobd.page_id, 'DETAILED') as ddpi
WHERE DB_NAME(dobd.database_id) = 'SampleDb'
AND OBJECT_NAME(ddpi.object_id) = 'SampleTable1'
GROUP BY dobd.database_id, ddpi.object_id, dobd.page_type;

-- SampleTable1 のページは以下の結果であった。
-- INDEX_PAGE:372
-- DATA_PAGE:100000



以上