続・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 モンキーターン