続・INDEXに関する検証 その5

<続・INDEXに関する検証 その5> ペンネーム モンキーターン

前回までのメルマガで、大量の削除処理によって INDEX内に空の BLOCKが数多
く発生し、空の BLOCKまでもがアクセスの対象となってしまう原因については
理解していただいたと思う。
今回は、その原因について検証を交えながら説明していこう。

— どっぷり検証生活 START! —

前回のメルマガで、flag = Dで管理(INDEX・キーが削除されると、そのキー自
体は削除されず、flag = Dとして管理される)されている INDEX・キーが開放
される流れを見てきた。

前回の検証テーブル(flag = Dで管理されている INDEX・キーが開放された後)
に対して、INDEXの RANGE検索を実行すると空の BLOCKまでもがアクセスの対象
となってしまう。
なぜ、空の Leaf_BLOCKにアクセスしてしまうのであろうか?
その原因を考えるとき、大切なのは INDEXの構造を把握していることと INDEX
のデータをアクセスするときの流れである。
Leaf_BLOCKがいくら flag = Dで管理されている INDEX・キーを開放して空の
Leaf_BLOCKになったとしても、アクセス管理している Branch_BLOCKや Root_
BLOCKも不要な Leaf_BLOCKデータ(空の Leaf_BLOCKデータ)を開放しないと
意味がないと言うことである。

よって今回は、Branch_BLOCKを中心に見ていこう。

<<<検証用テーブルとINDEXの作成>>>

1.ユーザー SCOTTで EMP_TESTと言うデータ件数が 1万件のテーブルを作成
(中身は EMP表と同じ、ただし EMPNOは ROWNUM順に UPDATEした。)
2.表の項目 EMPNOに対して、EMP_TEST_INDEXと言う INDEXを作成
(INDEXは別の表領域に作成)

<<<結果>>>

<<delete前の TREEDUMP・Branch_BLOCK_DUMP>>

<TREEDUMP>

----- begin tree dump
branch: 0x2400003 37748739 (0: nrow: 91, level: 1)
leaf: 0x2400004 37748740 (-1: nrow: 116 rrow: 116)-----→(1)
leaf: 0x2400005 37748741 (0: nrow: 110 rrow: 110)------→(2)
・
中略
・
leaf: 0x240005d 37748829 (88: nrow: 110 rrow: 110)
leaf: 0x240005e 37748830 (89: nrow: 94 rrow: 94)
----- end tree dump

<Branch_BLOCK_DUMP>

Branch block dump
=================
header address 71838788=0x4482c44
kdxcolev 1
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 90
kdxcofbo 208=0xd0
kdxcofeo 1106=0x452
kdxcoavs 898
kdxbrlmc 37748740=0x2400004          -----------------→(3)
kdxbrsno 0
kdxbrbksz 1916
row#0[1907] dba: 37748741=0x2400005  -----------------→(4)
col 0; len 3; (3):  c2 02 12
col 1; TERM
row#1[1898] dba: 37748742=0x2400006
col 0; len 3; (3):  c2 03 1c
col 1; TERM
・
中略
・
row#88[1115] dba: 37748829=0x240005d
col 0; len 3; (3):  c2 62 62
col 1; TERM
row#89[1106] dba: 37748830=0x240005e
col 0; len 3; (3):  c2 64 08
col 1; TERM
----- end of branch block dump -----

ここで、Branch_BLOCK_DUMPの見方を簡単に説明する。
まず、見ていただきたいのは<Branch_BLOCK_DUMP>の(4)である。これは、
<TREEDUMP>の(2)のLeaf_BLOCKの場所を示している。10進数のDBAが同一
ということから判断できる。
<Branch_BLOCK_DUMP>の(3)は、(4)以下のINDEX・キー(この例だと(4)
の col 0; c2 02 12(EMPNO=117)より下の値)は、すべて(3)で指定した Le
af_BLOCKに入りなさいということである。同様にcol 0; c2 02 12(EMPNO=117)
以上で col 0; len 3; (3): c2 03 1c(EMPNO=227)より下の値は(4)のLeaf_
BLOCKに入りなさいということを意味している。簡単に言ってしまえば、Branch_
BLOCKは「より下リスト」を持っていて、それを用いてどのLeaf_BLOCKに入るか
を決めているだけである。

<<delete直後の TREEDUMP・Branch_BLOCK_DUMP>>

<TREEDUMP>

----- begin tree dump
branch: 0x2400003 37748739 (0: nrow: 91, level: 1)
leaf: 0x2400004 37748740 (-1: nrow: 116 rrow: 0)
leaf: 0x2400005 37748741 (0: nrow: 110 rrow: 0) ------→(5)
・
中略
・
leaf: 0x240005d 37748829 (88: nrow: 110 rrow: 110)
leaf: 0x240005e 37748830 (89: nrow: 94 rrow: 94)
----- end tree dump

<Branch_BLOCK_DUMP>

Branch block dump
=================
header address 71838788=0x4482c44
kdxcolev 1
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 90
kdxcofbo 208=0xd0
kdxcofeo 1106=0x452
kdxcoavs 898
kdxbrlmc 37748740=0x2400004
kdxbrsno 0
kdxbrbksz 1916
row#0[1907] dba: 37748741=0x2400005
col 0; len 3; (3):  c2 02 12
col 1; TERM
row#1[1898] dba: 37748742=0x2400006
col 0; len 3; (3):  c2 03 1c
col 1; TERM
・
中略
・
row#88[1115] dba: 37748829=0x240005d
col 0; len 3; (3):  c2 62 62
col 1; TERM
row#89[1106] dba: 37748830=0x240005e
col 0; len 3; (3):  c2 64 08
col 1; TERM
----- end of branch block dump -----

delete直後の TREEDUMPは、delete前の<TREEDUMP>(2)の rrows = 110から
delete直後の<TREEDUMP>(5)の rrowsが 0になり DELETEされているのが確
認できる。
一方、Branch_BLOCK_DUMPは、delete前の Branch_BLOCK_DUMPと異なる点は見
受けられなかった。
delete処理を実行しても Branch_BLOCK_DUMPの管理は変わらないのである。

<<delete後、INDEXの RANGE検索直後の TREEDUMP・Branch_BLOCK_DUMP>>

<TREEDUMP>

----- begin tree dump
branch: 0x2400003 37748739 (0: nrow: 91, level: 1)
leaf: 0x2400004 37748740 (-1: nrow: 0 rrow: 0)
leaf: 0x2400005 37748741 (0: nrow: 0 rrow: 0) --------→(6)
・
中略
・
leaf: 0x240005d 37748829 (88: nrow: 110 rrow: 110)
leaf: 0x240005e 37748830 (89: nrow: 94 rrow: 94)
----- end tree dump

<Branch_BLOCK_DUMP>

Branch block dump
=================
header address 71838788=0x4482c44
kdxcolev 1
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 90
kdxcofbo 208=0xd0
kdxcofeo 1106=0x452
kdxcoavs 898
kdxbrlmc 37748740=0x2400004
kdxbrsno 0
kdxbrbksz 1916
row#0[1907] dba: 37748741=0x2400005
col 0; len 3; (3):  c2 02 12
col 1; TERM
row#1[1898] dba: 37748742=0x2400006
col 0; len 3; (3):  c2 03 1c
col 1; TERM
・
中略
・
row#88[1115] dba: 37748829=0x240005d
col 0; len 3; (3):  c2 62 62
col 1; TERM
row#89[1106] dba: 37748830=0x240005e
col 0; len 3; (3):  c2 64 08
col 1; TERM
----- end of branch block dump -----

delete後で INDEXの RANGE検索直後の TREEDUMPは、delete直後の<TREEDUMP>
(2)の nrows = 110から delete後で INDEXの RANGE検索直後の<TREEDUMP>
(6)の nrowsが 0になり flag = Dで管理されていた INDEX・キーが開放され
ているのが確認できる。ここまでは、以前 行なったLeaf_BLOCKの検証結果と同
じである。
一方、Branch_BLOCK_DUMPは、delete前の Branch_BLOCK_DUMP、delete後の
Branch_BLOCK_DUMPと異なる点は見受けられなかった。
flag = Dで管理されていた INDEX・キーが開放されても Branch_BLOCK_DUMPの
管理はやはり変わらないのである。

今回の結果より、空の Leaf_BLOCKにアクセスしてしまう原因がわかっていた
だいたと思う。
要するに、Leaf_BLOCK内でどのようなことが起きても、アクセス経路を管理し
ているのは Branch_BLOCKなので、空の Leaf_BLOCKだろうが INDEX・キーの入
った Leaf_BLOCKだろうが Branch_BLOCKがその Leaf_BLOCKを管理していれば
検索条件に引っかかるために無駄な I/Oが発生するのである。

次回は、Branch_BLOCKの管理によって、INSERT処理で Leaf分割が多発する現
象を報告する予定である。

冒頭で説明したORACLEと親和性のあるWEBに適した新言語 自社開発フリーソフト
言語「SQeeL」のこともよろしくお願いします!!!!
*詳細をご希望の方は、弊社までお問い合わせください。
mailto:insight-mktg@insight-tec.co.jp

スコール 茅ヶ崎にて

~続・INDEXに関する検証 その5~
by モンキーターン