データのキャッシュのしくみについていくつか質問があります
以下の状況を想像してください:
サーバーが再起動されたか、実行されましたDBCC DROPCLEANBUFFERS
Table1
50 GBで、列A
、B
、C
、D
、E
があります。
列A
はクラスター化インデックスキーであり、列B
およびC
には非クラスター化インデックスがあります。
私たちがするとき
select top 100 * from Table1
100行しか必要ない場合でも、クラスター化インデックス全体(テーブル)がディスクからメモリに読み取られていますか?または、100行(データページ)がディスクからメモリに読み取られますか?
実行すると、非クラスター化インデックスと同じ
select top 100 * from Table1 where column B = 'some value'
非クラスター化インデックス+クラスター化インデックス全体がメモリに読み込まれますか?または、非クラスター化インデックスの100行とクラスター化インデックスの100行だけですか?
テストデータ
CREATE TABLE dbo.Table1( A INT IDENTITY(1,1) PRIMARY KEY NOT NULL
,B varchar(255),C int,D int,E int);
INSERT INTO dbo.Table1 WITH(TABLOCK)
(B,C,D,E)
SELECT TOP(1000000) 'Some Value ' + CAST((ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) % 400) as varchar(255))-- 400 different values
,ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
,ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
,ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
FROM master..spt_values spt1
CROSS APPLY master..spt_values spt2;
CREATE INDEX IX_B
On dbo.Table1(B);
CREATE INDEX IX_C
On dbo.Table1(C);
「表1から上位100 *を選択」を実行すると、クラスター化インデックス(テーブル)全体がディスクからメモリに読み込まれます。または、100行(データページ)がディスクからメモリに読み込まれますか?
クラスター化インデックスから100行のみが読み取られます。その結果、データページのみがメモリにキャッシュされます。
例
私の場合、クラスタードインデックスから下向きに読み取られ、列A
の値は1〜100です。
SET STATISTICS IO, TIME ON;
select top 100 * from dbo.Table1
読み取り:
Table 'Table1'. Scan count 1, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
4論理読み取り= 4ページ
なぜまだscan count = 1
、 だけ 4
論理読み取りは、あなたが尋ねるかもしれませんか?
範囲スキャンを実行しているため:
最上位の演算子を満たすため。
非クラスター化インデックスと同様に、「列B = '値'であるTable1から上位100 *を選択」を実行すると、非クラスター化インデックス全体+クラスター化インデックスがメモリに読み込まれますか?または非クラスタ化インデックスから100行+クラスタ化インデックスから100行?
例1
SET STATISTICS IO, TIME ON;
select top 100 * from dbo.Table1
WHERE B='Some Value 200'
ここでは非クラスター化インデックスが使用されることが予想されますが、実際にはクラスター化インデックスが引き続き使用されます。
キャッシュをクリアした後287
論理読み取り&2528
先読み。
Table 'Table1'. Scan count 1, logical reads 287, physical reads 1, read-ahead reads 2528, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
これらの先読み読み取りをディスクから読み取り、次に287
メモリからのページ。
先読みメカニズムはSQL Serverの機能であり、クエリによってデータが要求される前でも、データページをバッファキャッシュに取り込みます。 ソース
キャッシュされたページをチェックした場合:
cached_pages_count objectname indexname indexid
2536 Table1 PK__Table1__3BD019AE039DA497 1
これも表示されています。
したがって、この場合は、より多くのページをキャッシュしてクエリにすばやく対応します。これは、残りの述語を適用するためにより多くの行を読み取るためです。
ただし、これらのページはclusteredインデックスからのみ読み取っています。
例2
非クラスター化インデックスを利用することを期待して、クエリを変更できます。
select top 100 B from dbo.Table1
WHERE B='Some Value 200';
それはどちらですか:
これも小さな範囲スキャンを提供します:
Table 'Table1'. Scan count 1, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
ここでは、nonclusteredインデックスページのみがメモリに読み込まれます。
例3
インデックスヒントを使用して、例1のクエリを満たすようにキー検索を強制できます。
SET STATISTICS IO, TIME ON;
select top 100 *
from dbo.Table1
WITH(INDEX(IX_B))
WHERE B='Some Value 200';
これにより、先読みがいくつか発生し、example1よりも論理的な読み取りが多くなります。
Table 'Table1'. Scan count 1, logical reads 684, physical reads 3, read-ahead reads 465, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
非クラスター化からクラスター化インデックスへのキールックアップを行っているので、両方のインデックスのページをキャッシュします。
100行だけが必要な場合でも?または100行(データページ)がディスクからメモリに読み込まれますか?
TOP
句が論理シーケンスの最後に考慮されるため、SQLクエリの論理処理順序が原因である可能性があります。 詳細については.. 。したがって、WHERE
句にフィルターを適用すると、TOP 100
を適用せずに100行のみを返すと、読み取られるページが少なくなります。