0
2

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.

1行が1ページを超えるときのデータ格納(Row-Overflow編その2)

Posted at

#はじめに
前回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がその対象となるはずだ。

#検証
まずはdbcc indの結果から。
mikkame1.PNG

今回投入した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

0
2
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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?