連載
» 2010年01月18日 00時00分 公開

リーフ分割検証:意外と増えていたリーフブロック!おら! オラ! Oracle再検証 @IT出張所(2)(2/4 ページ)

[内山義夫,株式会社インサイトテクノロジー]

手順1 まずはデータの作成

 では手順1を実行してみましょう。ここでは、10000001から11000000の間で末尾が0の値を10万件作成しています。

SQL> BEGIN
  2     FOR i IN 1..100000 LOOP
  3        INSERT INTO INDEX_TEST
  4        VALUES(10000000 + (i * 10),10000000 + (i * 10),'SCOTT','ENGINEER',9999,SYSDATE,1024,100 );
  5     END LOOP;
  6     COMMIT;
  7  END;
  8  /
PL/SQL procedure successfully completed.
手順1:データ作成(10万件)

 上記では末尾が0のデータを10万件挿入しています。この手順のポイントは、EMPNO1とEMPNO2に格納している値を、1ずつではなく10ずつ値を増加させている点です(10000010、10000020、10000030……11000000)。これは、手順2でその間の値を挿入させてリーフ分割を発生させるようにするためです。

SQL> SELECT OBJECT_NAME,OBJECT_ID
  2    FROM USER_OBJECTS
  3   WHERE OBJECT_NAME In( 'IDX_INDEX_TEST') ;
OBJECT_NAME           OBJECT_ID
-------------------- ----------
IDX_INDEX_TEST            73010
SQL> ALTER SESSION SET EVENTS 'IMMEDIATE TRACE NAME TREEDUMP LEVEL 73010';
TREEDUMP取得コマンド

 TREEDUMPを取得した結果を図にすると、以下のようになります。

図1 手順1実行後のインデックス 図1 手順1実行後のインデックス

リーフブロックの追加

 今回実行したプロシージャでは、リーフ分割は発生せず新たなリーフブロックが追加されています。この点について実際に確認してみましょう。

 確認は、INSERT文の直後にTREEDUMPを取得するコマンドを実行するように変更して、インデックスのTREEDUMPがどのようになるかその推移を見ます。

SQL> BEGIN
   2     FOR i IN 1..100000 LOOP
   3        INSERT INTO INDEX_TEST
   4        VALUES(10000000 + (i * 10),10000000 + (i * 10),'SCOTT','ENGINEER',9999,SYSDATE,1024,100 );
   5        EXECUTE IMMEDIATE 'ALTER SESSION SET EVENTS ''IMMEDIATE TRACE NAME TREEDUMP LEVEL 73010''';
   6     END LOOP;
   7     COMMIT;
   8  END;
   9  /PL/SQL procedure successfully completed.
【注1】
トレースファイルが大量に出力されますので、実際に上記を実行するときは件数を絞って実行してください。

 ----- begin tree dump
   leaf: 0x2c002a5 46138021 (0: nrow: 1 rrow: 1)
   ----- end tree dump
   ----- begin tree dump
   leaf: 0x2c002a5 46138021 (0: nrow: 2 rrow: 2)
   ----- end tree dump
   ----- begin tree dump
   leaf: 0x2c002a5 46138021 (0: nrow: 3 rrow: 3)
   ----- end tree dump
   ----- begin tree dump
          ・  
          ・  
          ・  
   leaf: 0x2c002a5 46138021 (0: nrow: 105 rrow: 105)
   ----- end tree dump
   ----- begin tree dump
   leaf: 0x2c002a5 46138021 (0: nrow: 106 rrow: 106)
   ----- end tree dump
   ----- begin tree dump
   leaf: 0x2c002a5 46138021 (0: nrow: 107 rrow: 107)
   ----- end tree dump
   ----- begin tree dump
   leaf: 0x2c002a5 46138021 (0: nrow: 108 rrow: 108)
   ----- end tree dump
   ----- begin tree dump
   leaf: 0x2c002a5 46138021 (0: nrow: 109 rrow: 109) ←★Point1
   ----- end tree dump
   ----- begin tree dump
   branch: 0x2c002a5 46138021 (0: nrow: 2, level: 1)
   leaf: 0x2c002b7 46138039 (-1: nrow: 109 rrow: 109)
   leaf: 0x2c002a6 46138022 (0: nrow: 1 rrow: 1) ←★Point2 新規ブロック追加
   ----- end tree dump
   ----- begin tree dump
   branch: 0x2c002a5 46138021 (0: nrow: 2, level: 1)
   leaf: 0x2c002b7 46138039 (-1: nrow: 109 rrow: 109)
   leaf: 0x2c002a6 46138022 (0: nrow: 2 rrow: 2)
   ----- end tree dump
   ----- begin tree dump
   branch: 0x2c002a5 46138021 (0: nrow: 2, level: 1)
   leaf: 0x2c002b7 46138039 (-1: nrow: 109 rrow: 109)
   leaf: 0x2c002a6 46138022 (0: nrow: 3 rrow: 3)
   ----- end tree dump 
トレースを一部抜粋

 TREEDUMPを見ると、★Point 1で109行目を格納しており、★Point 2で新たなブロックが追加されています。それぞれのブロックの行数をみると、基のリーフブロックの行数は109行(nrow: 109 rrow: 109)であり、新たに追加されたブロックは1行(nrow: 1 rrow: 1)です。リーフ分割が発生すれば行数が半分に分割されますが、今回のプロシージャではリーフ分割は発生せずにリーフブロックが新たに追加されたということが分かります。

 つまり、小さい値から順にブロックに値が格納されていけば、リーフ分割は発生せず、新たなリーフが追加されるということになります。ある意味予想通りの結果といえます。

 続いて、手順2を実行しましょう。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。