0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

参照ページ数の確認

Last updated at Posted at 2018-01-04

#はじめに
今までの実験で、テーブル定義によってIn-row dataとRow-overflow dataのページが作成されることを確認してきたが、単純に読み込んだページ数を確認するだけならSET STATISTICS IO ONを利用するのが簡単だ。
※実はSET STATISTICS IOの結果を理解するために今までのステップを踏んできた。

#実験
dbo.yokkameテーブルを作成。セットする文字列長により、In-rowには列c1, c2が収まり、列c3, c4, c5がRow-overflow dataページに格納されるはず。
そしてデータは5行投入するので、In-rowが5ページ、Row-overflowが3x5=15ページ作成されるはずだ。

if Exists(
    Select * 
    From INFORMATION_SCHEMA.TABLES 
    Where TABLE_SCHEMA = 'dbo' and TABLE_NAME = 'yokkame'
)

Drop Table dbo.yokkame;
GO

CREATE TABLE dbo.yokkame (
    [c1] [int] NOT NULL,
    [c2] [nvarchar](3600) NULL,
    [c3] [nvarchar](3800) NULL,
    [c4] [nvarchar](3800) NULL,
    [c5] [nvarchar](3800) NULL
);
GO

-- データ投入
Declare @s nvarchar(3800);
Set @s = replicate('0123456789',380);

Insert into dbo.yokkame Values(1, replicate('0123456789', 360), @s, @s, @s);
Insert into dbo.yokkame Values(2, replicate('0123456789', 360), @s, @s, @s);
Insert into dbo.yokkame Values(3, replicate('0123456789', 360), @s, @s, @s);
Insert into dbo.yokkame Values(4, replicate('0123456789', 360), @s, @s, @s);
Insert into dbo.yokkame Values(5, replicate('0123456789', 360), @s, @s, @s);
GO

今まで同様、dbcc indの結果を確認する。
yokkame1.PNG

予想通り、PageType=1のIn-row dataが5行、PageType=3のRow-overflow dataが15行作成された。

これをSET STATISTICS IO ONにしてSeelctするとこうなる。
※結果をメッセージペインに切り替えてます。
yokkame2.PNG

詳細はMS公式サイトを見てもらうとして、確かにIn-rowで5ページ、Row-overflowで(表記上はLOBとしてまとめられているが)15ページの読み取りが発生している。

#追加実験
上図において「物理読み取り数」はIn-row, Row-overflowともにゼロとなっている。
これはInsertした時点のデータがバッファプール(メモリキャッシュ)に残っているからだと考えられる。
ではサービス起動直後ならばディスクからの初回読み取りが発生するので、物理読み取り数がカウントされるのではないだろうか。

ということで、SQLServerのサービスを再起動し、全行Selectしてみた。

結果はこちら。
yokkame3.PNG

予想に反して、In-rowの物理読み取りが1、Row-overflowの物理読み取りが2となった。
しかも論理読み取り数は先ほどの結果と変わらない。

これは実際のI/Oは連続した8ページ(エクステント)単位で行われる、ということに起因していると思われる。
dbcc indの結果(上図)を見ていただくと、In-row dataに関しては5ページ分なので、実際のdisk I/Oは1回で済んでいるはずだ。PagePIDも424~428の連続した5個となっている。
同様にRow-overflowについては全部で15行あるので、エクステントとしては2回読み取りを行っているはずだ。PagePIDも、408~415と、432~438の2区間に分かれている。

ただ公式サイトでは「物理読み取りページ数」となっていて、「物理読み取り回数」ではないので、上記の推測は外れているかもしれない。

調査は追ってやるとして、さらに大量データで確認してみよう。

#追加実験その2
大量データ投入

Truncate Table dbo.yokkame;
GO

Declare @strseed nchar(10);
Set @strseed = '0123456789';

Declare @str3600 nvarchar(3600);
Set @str3600 = replicate(@strseed,360);

Declare @str3800 nvarchar(3800);
Set @str3800 = replicate(@strseed,380);


with N1(dummy) as (Select 0 union all Select 0)  -- 2 rows
,N2(dummy) as (Select 0 From N1 as T1 cross join N1 as T2) -- 4rows
,N3(dummy) as (Select 0 From N2 as T1 cross join N2 as T2) -- 16rows
,N4(dummy) as (Select 0 From N3 as T1 cross join N3 as T2) -- 256rows
,N5(dummy) as (Select 0 From N4 as T1 cross join N2 as T2) -- 1024rows
,IDs(id) as (Select ROW_NUMBER() over (order by (select null)) from N5)

Insert into dbo.yokkame
Select id, @str3600, @str3800, @str3800, @str3800
From IDs;
GO

上記CTE式の部分は参考書籍の真似なのだが、こんな使い方があるのかとびっくり。
View定義などで長いSelect文を分解して視認性を上げたいときにCTEを使うことは知っていたけど(複数定義を並べるとき、前方で定義したものを後方で使えるので便利)、これは思いつかなかった。
しかも見て分かりやすい。
最後のorder by (select null)も脱帽。
すっすいません、知りませんでした...

次にdbcc indの結果を集計して、合計何ページ分を消費しているか確認する。

Declare @result_ind table(
    PageFID int,
    PagePID int,
    IAMFID int,
    IAMPID int,
    ObjectID int,
    IndexId int,
    PartitionNumber bigint,
    PartitionID bigint,
    iam_chain_type sysname,
    PageType int,
    IndexLevel int,
    NextPageFID int,
    NextPagePID int,
    PrevPageFID int,
    PrevPagePID int
);

Declare @stat nvarchar(1000);
Set @stat = 'dbcc ind(''GHJK'', ''dbo.yokkame'', -1)';

Insert into @result_ind Exec(@stat);

Select iam_chain_type, Count(*) as number_of_pages
From @result_ind
Where PageType in(1, 3)
Group by iam_chain_type;
GO

※なお作業中の食欲を抑えるため、DB名は変更済。
さて、上記の結果はというと...
yokkame4.PNG

Row-overflow dataは、レコード数の3倍あるはず。
1024 x 3 = 3072
予定どおりの結果となった。

そして最後に、サービスを再起動してSelectしてみます。

SET STATISTICS IO ON で Selectした結果は...
yokkame5.PNG

LOBのほうは予想通り。物理読み取り数384ってことは、384 x 8 = 3,072
なので、これは「物理的に読みに行った回数」ってことでいいのではないかと思う。
※混合エクステントになると単純に8倍にならなくなると思うので、エクステント数ではなく読み取り回数なのだろう。

一方In-rowのほうは、物理読み取りではなく「先行読み取り数」にカウントが入った。
値自体は1,024で問題なし。

ひとまず今回はここまで。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?