#はじめに
前回Row-overflowの様子を確認したが、もう少し踏み込んでみたい。
まずは「実際に格納されているデータの長い順にRow-overflow data」領域に移動される、という点から。
#実験の概要
可変長フィールドを2つ用意し、データを2行用意。
1行目と2行目でセットする実データの長さを変え、異なるフィールドが最大長になるような状況を作る。
#実験スタート
-- 実験用テーブル作成
Use DORAYAKI;
GO
if Exists(
Select *
From INFORMATION_SCHEMA.TABLES
Where TABLE_SCHEMA = 'dbo' and TABLE_NAME = 'mikkame'
)
Drop Table dbo.mikkame;
GO
CREATE TABLE dbo.mikkame (
[c1] [int] NOT NULL,
[c2] [nvarchar](3800) NULL,
[c3] [nvarchar](3600) NULL
);
GO
-- データ投入
Insert into dbo.mikkame Values(1, replicate('0123456789',380), replicate('0123456789', 360));
Insert into dbo.mikkame Values(2, replicate('0123456789',340), replicate('0123456789', 360));
GO
実際のデータ長でRow-overflow行きの列が判断されるのであれば、1行目は列c2が、2行目は列c3がその対象となるはずだ。
今回投入した2行のデータは、列c2, c3は、3400文字(6,800bytes)~3800文字(7,600bytes)ということで、それぞれ単独で1ページを占領するように設定した。
dbcc indの結果でも、In-rowとRow-overflowが2行ずつ見える。(PageType=10は除く)
ではいよいよ、どの列がoverflow行きになっているかを確認しよう。
まずはIn-rowの1行目、PagePID = 408のほうから、dbcc pageの結果。
※今回は見たいところが今までと違うので、掲載箇所・編集も変えてあります。
(ここまで省略)
Slot 0 Column 1 Offset 0x4 Length 4 Length (physical) 4
c1 = 1
c2 = [BLOB Inline Root] Slot 0 Column 2 Offset 0x11 Length 24 Length (physical) 24
Level = 0 Unused = 0 UpdateSeq = 1
TimeStamp = 1102774272 Type = 2
Link 0
Size = 7600 RowId = (1:376:0)
Slot 0 Column 3 Offset 0x29 Length 7200 Length (physical) 7200
c3 = 01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
(以下省略)
このように、列c2がOverflowされていることが確認できた。
次にIn-rowの2行目、PagePID = 409のdbcc pageの結果。
(ここまで省略)
Slot 0 Column 1 Offset 0x4 Length 4 Length (physical) 4
c1 = 2
Slot 0 Column 2 Offset 0x11 Length 6800 Length (physical) 6800
c2 = 01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
(中略)
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
c3 = [BLOB Inline Root] Slot 0 Column 3 Offset 0x1aa1 Length 24 Length (physical) 24
Level = 0 Unused = 0 UpdateSeq = 1
TimeStamp = 652804096 Type = 2
Link 0
Size = 7200 RowId = (1:377:0)
(以下省略)
予定どおり、列c3がoverflowされていることが確認できた。
#追加実験
値をUpdateして、最長列を切り替えてみる。
Update dbo.mikkame
Set c2 = replicate('0123456789',320)
Where c1 = 1;
GO
これで1行目の最長列は、列c2から列c3に切り替わったはず。
早速dbcc pageで確認だ。
dbcc traceon(3604);
dbcc page('DORAYAKI', 1, 408, 3);
Slot 0 Column 1 Offset 0x4 Length 4 Length (physical) 4
c1 = 1
Slot 0 Column 2 Offset 0x11 Length 6400 Length (physical) 6400
c2 = 01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
(中略)
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
c3 = [BLOB Inline Root] Slot 0 Column 3 Offset 0x1911 Length 24 Length (physical) 24
Level = 0 Unused = 0 UpdateSeq = 1
TimeStamp = 571670528 Type = 2
Link 0
Size = 7200 RowId = (1:378:0)
(以下省略)
文字数を3200文字=6,400bytesにUpdateしたことで、Row-overflowの対象列が切り替わった。
今回はサプライズなし!
#感想
- 内部ではとんでもない処理を行っているなと思う。
- In-rowだけのテーブルとRow-overflowを伴うテーブルで、パフォーマンス対決をしてみたい。
THE END