検索
連載

Bツリーインデックスに最高のパフォーマンスをOracleパフォーマンス障害の克服(3)(2/4 ページ)

Oracleデータベースの運用管理者は、突発的に直面するパフォーマンス障害にどうやって対処したらよいか。本連載は、非常に複雑なOracleのアーキテクチャに頭を悩ます管理者に向け、短時間で問題を切り分け、対処法を見つけるノウハウを紹介する。対象とするバージョンはOracle8から9iまでを基本とし、10gの情報は随時加えていく。(編集局)

Share
Tweet
LINE
Hatena

データの更新・削除に伴うリーフの変化

 さらに踏み込んで、データの更新・削除に伴いリーフがどのような状況になるか確認してみます。確認する項目としてはリーフの数がどのようになっているか、削除されたリーフはあるのかという観点が重要です。なおデータ追加時のリーフやブランチの数やリーフ行の動きはデータ量やシステムの構成に依存しますので、下記のリーフやブランチになるとは限りません(下記に示す図ではリーフ行が2行しかありませんが、実際のインデックスが必ず2行ということではありません)。

情報取得SQL文

SQL> ANALYZE INDEX インデックス名 VALIDATE STRUCTURE;
 SQL> SELECT LF_ROWS AS "リーフ行の数",
      LF_BLKS AS リーフブロック数,
      DEL_LF_ROWS AS "削除リーフ行の数",
      TO_CHAR(DEL_LF_ROWS/LF_ROWS * 100,'999.9') || '%' AS "削除リーフ行の割合"
      FROM INDEX_STATS;

 INDEX_STATSから情報を取得するには、ANALYZEコマンドを使用して状況を分析し、情報を取得する必要がありますのでINDEX_STATSのSELECT文の前に必ず実行します。

 では、テーブルデータの更新時にインデックスがどのように変化していくか確認してみます。先ほどの図1を基に、まずはデータを削除した場合を確認してみましょう。テストデータの作成は以下のようなスクリプト、構成で行います。

テーブル:
 CREATE TABLE test_table(no number, data VARCHAR2(20));
 
データ: テストデータを1000件挿入
 BEGIN
     FOR i IN 1..1000 LOOP
       INSERT INTO test_table(no,data)
       VALUES((i * 100), TO_CHAR('data_' || (i * 100)));
     END LOOP;
 END;
 /
 
インデックス:
 CREATE INDEX idx_test_table ON test_table(no);
テストデータ作成画面
テストデータ作成画面(クリックで拡大します)
テストデータ内容
テストデータ内容
テストデータ挿入後のインデックスの状態
テストデータ挿入後のインデックスの状態(クリックで拡大します)

1. データを削除した場合

図2 データテーブルからデータを削除したときのBツリーインデックス
図2 データテーブルからデータを削除したときのBツリーインデックス
※DBAの値として記載している「DBA1、…」はアドレスを示す例である
※ROWIDの値として記載している「ROWID1、…」はアドレスを示す例である

 図2のように、実際のテーブルデータは削除され、リーフノードの対応するデータが削除されます。

SQL結果画面
SQL結果画面(クリックで拡大します)

 リーフブロック数は変わらず、削除リーフ行が増加し、削除されたリーフの割合が高くなっていることが重要です。

2. リーフの範囲内のすべてのデータを削除した場合

 図2を確認すると分かるように、実際のテーブルデータは削除され、リーフノードの対応するデータが削除されるのですが、1つのリーフそのものが空のリーフとして残ってしまいます。

SQL結果画面
SQL結果画面(クリックで拡大します)

 リーフブロック数は変わらず、削除リーフ行が増加し、削除されたリーフの割合が高くなっていることが重要です。つまり、空のリーフブロックが残ってしまっています。(次ページに続く)

Copyright © ITmedia, Inc. All Rights Reserved.

ページトップに戻る