2003年 7月 1日 「INDEX-only」 の簡単な例 >> 目次 (作成日順)


 
データ 構造

 以下の データ 構造を前提にする。

 顧客 { 顧客番号、顧客名称 } [ R ]

 商品 { 商品番号、商品名称、商品単価 } [ R ]

 受注 { 受注番号、顧客番号 (R)、商品番号 (R)、受注日、受注数 } [ E ]

 

 
キー の定義表

 画面と 「キー の定義表」 は以下を前提にする。



受注照会画面
 顧客番号:  顧客名称:
 受注番号:  受注日:
 商品番号:  商品名称:  受注数:  商品単価:


顧客 テーブル N+M key-1                
 顧客番号 1                
 顧客名称   2                


受注 テーブル N+M key-1                
 受注番号 2 2                
 顧客番号 (R) 1 1                
 品目番号 (R)   3                
 受注日   4                
 受注数   5                


商品 テーブル N+M key-1                
 商品番号 1                
 商品名称   2                
 商品単価   3                


 
プログラム (SQL) の例

 (1) 顧客 テーブル、受注 テーブル および商品 テーブル に対する DDL

    CREATE INDEX (顧客番号, 顧客名称).
    CREATE INDEX (顧客番号, 受注番号, 商品番号, 受注日, 受注数).
    CREATE INDEX (商品番号, 商品名称, 商品単価).

 (2) 顧客 テーブル に対する DML

    SELECT 顧客名称
    FROM  顧客
    WHERE 顧客番号 = "入力値".

 (3) 受注 テーブル の対する DML

    SELECT 商品番号 受注日 受注数
    FROM  受注
    WHERE 顧客番号 = "入力値"
               AND
          受注番号 = "入力値".

 (4) 商品 テーブル の対する DML

    SELECT 商品名称 商品単価
    FROM  商品
    WHERE 商品番号 = "WK- 商品番号".

 
[ 参考 ]
 (1) は、「CREATE INDEX」 であって、「CREATE VIEW」 ではない点に注意されたい。
 (2) のなかで リターン 値として得た商品番号は ワークエリア に収めておかなければならない。

 テーブル に対する アクセス は、一切、ない。
 なぜなら、インデックス を読み込んだ時点で、インデックス のなかに データ が収められているから。
 つまり、インデックス のみに アクセス して データ を得ることができるので、これを 「INDEX-only」 という。

   たとえば、複数の商品を表示するとしても、それらの商品は インデックス のなかで昇順に並んでいるので、「order-by」 を記述しなくてもよい。

 対象となる データ 件数が多ければ多いほど、table-scan の 「CREATE INDEX」 に比べて、「INDEX-Only」 は I/O 回数の少ない 「驚異的な」 高 パフォーマンス を実現する。
 さらに、インデックス を使った join (inner-join) のほうが、outer-join をしてから order-by を実行ことに比べたら、「驚異的な」 高 パフォーマンス を実現する。

 なお、「INDEX-only」 は、複合選択条件 (「AND」 あるいは 「OR」 を使った検索) において、「AND」 にも 「OR」 にも使うことができる--「OR」 を使って 2つ以上の カラム が合致しても、同一ROW の カラム であれば、検索結果として、1つの ROW しか表示しない (DB2 および ORACLE で動作確認済み)。

 
「INDEX-only」 使用上の注意点

 「INDEX-only」 は、たしかに、「驚異的な」 高 パフォーマンス を実現するが、万能薬ではない。
 以下の諸点に注意されたい。

 (1) データ 件数が少ないと効果がない。
   なぜなら、データ が メモリー のなかに収まるから。
   「INDEX-only」 は、多量 データ および多量 トランザクション を対象とする基幹系 システム 向きである。

 (2) テーブル に対する更新 (ADD, CHANGE, DELETE) が多いことを前提にすれば、
   1つの テーブル に対する 「CREATE INDEX」 の数を制限しなければならない。
    - DB2 あるいは ORACLE なら、1つの テーブル に対して 5つ以内にする。
    - SQL/Server あるいは PostgreSQL なら、1つの テーブル に対して 3つ以内にする。

 (3) データ の ロード がおそくなる。
   なぜなら、複数の インデックス も同時に生成するから。

 (4) インデックス・エリア が大きくなる。データ・エリア よりも大きくなることがある。
   インデックス・エリア の見積もりに注意されたい。

 そして、なによりも、テーブル を完全な正規形にしておかなければならない。
 正規形として テーブル を小さくして数が多くなると I/O 負荷が増えると思って、非正規化するなど言語道断である。
 テーブル が完全な正規形になって小さくなっていて、「INDEX-only」 の join (inner-join) をしたほうが I/O は圧倒的に減少する。

 [ 多量 データ および多量 トランザクション を前提とする ] 基幹系の システム に対して RDB を使って、「驚異的な」 高 パフォーマンス を実現するためには、以下の点を配慮すればいい。

 (1) テーブル が完全な正規形であること。
 (2) 「create view」 および 「order-by」 を使わないこと。
 (3) ディスク を多く用意すること (CPU は強力なくてもいい)。

 基幹系 システム というのは定型なので、アクセス・パス が、ほぼ、限られている。
 RDB は、(上述した点から判断できるように) 情報系よりも基幹系のほうが 「驚異的な」 高い パフォーマンス を実現できるのである。なぜなら、定型では、1つの テーブル に対して生成する インデックス の数は多くないから。

 なお、「INDEX-only」 を実行する際には、かならず、SQL の 「execution-plan」 を検証してほしい。
 「INDEX-SCAN」 と表示されていれば OK である。「TABLE-SCAN」 と表示されていたら、optimizer が 「INDEX-only」 を外しているので注意されたい (!)

 次回は、「I/O 計算」について述べる。




  << もどる HOME すすむ >>
  ベーシックス