DB2 10.5 for Linux, UNIX, and Windows

索引アクセスのタイプ

照会が必要としているデータすべてが表の索引から取得できると、 オプティマイザーが判断できる場合があります。 他方、表にアクセスするのに複数の索引を使用する場合もあります。 範囲がクラスター化された表の場合は、データ・レコードの位置を計算する「仮想」索引を介してデータにアクセスできます。

索引のみのアクセス

場合によっては、表にアクセスせずに、索引からすべての必須データを検索できることがあります。これは、索引のみのアクセス と呼ばれます。例えば、次の索引定義を考えてみてください。
   INDEX IX1:  NAME    ASC,
               DEPT    ASC,
               MGR     DESC,
               SALARY  DESC,
               YEARS   ASC
基本表を読み取らずに、索引にアクセスするだけで、以下の照会を実行することができます。
   select name, dept, mgr, salary
     from employee
     where name = 'SMITH'
しかし、必要な列が索引内にないことがよくあります。 それらの列からデータを取り出すには、表の行を読み取らなければなりません。 オプティマイザーが索引のみのアクセスを選べるようにするには、include 列を持つユニーク索引を作成します。 例えば、次の索引定義を考えてみてください。
   create unique index ix1 on employee
     (name asc)
     include (dept, mgr, salary, years)
この索引は NAME 列をユニークとし、さらに DEPT、MGR、SALARY、および YEARS 列のデータも保管して保守します。 このようにして、以下の照会は索引にアクセスするだけで達成できます。
   select name, dept, mgr, salary
     from employee
     where name = 'SMITH'

include 列を含める場合には、追加のストレージ・スペースと保守コストに見合うメリットがあるかどうかを考慮してください。 include 列を使用する照会がめったに実行されないのなら、コストに見合うメリットがあるとは言えないかもしれません。

複数の索引へのアクセス

WHERE 節の述部を実行するために、オプティマイザーが同じ表の複数の索引をスキャンすることを選択する場合があります。 例えば、以下の 2 つの索引定義を考えてみてください。
   INDEX IX2:  DEPT    ASC
   INDEX IX3:  JOB     ASC,
               YEARS   ASC
次の述部は上記の 2 つの索引を使用することにより実行できます。
   where
     dept = :hv1 or
     (job = :hv2 and
     years >= :hv3)

索引 IX2 をスキャンすることによって、 dept = :hv1 述部を満たすレコード ID (RID) のリストが作成されます。 また、索引 IX3 をスキャンすることによって、 job = :hv2 and years >= :hv3 述部を満たす RID のリストが作成されます。 表にアクセスする前に、これらの 2 つの RID リストは組み合わせられて重複は除去されます。 これは、索引 ORing と呼ばれます。

索引 ORing 操作は、次の例のように IN 節で指定されている述部でも使用することもできます。
   where
     dept in (:hv1, :hv2, :hv3)
索引 ORing の目的は、 重複した RID を除去することですが、 索引 ANDing 結合 の目的は、 共通 RID を検索することです。 索引 ANDing 結合は、同じ表内の対応する列に複数の索引を作成するアプリケーションが、 複数の AND 述部がある照会をこの表に対して実行する場合に行われることがあります。 索引付けされた列ごとに複数の索引スキャンを行うと、ビットマップを作成するためにハッシュされた値が生成されます。 1 番目のビットマップを厳密に調べるために 2 番目のビットマップが使用され、最終的な結果セットに対して適格となる行が生成されます。 例えば、以下のような索引があるとします。
   INDEX IX4: SALARY   ASC
   INDEX IX5: COMM     ASC
これを使用して次の述部を解決できます。
   where
     salary between 20000 and 30000 and
     comm between 1000 and 3000

この例では、索引 IX4 をスキャンすると、 salary between 20000 and 30000 述部を満たすビットマップが生成されます。 IX5 のスキャンおよび IX4 のビットマップのプローブを行うと、両方の述部を満たす、適格となる RID のリストが生成されます。 これは、動的ビットマップ ANDing と呼ばれます。これは、表に十分なカーディナリティーがあるか、その列の適格となる範囲内に十分な値があるか、または、 等価述部が使用される場合に十分な重複があるときにのみ行われます。

複数の索引をスキャンするときに動的ビットマップを使用してパフォーマンス上の利点を実現するためには、sortheap データベース構成パラメーターの値、 および sheapthres データベース・マネージャー構成パラメーターの値を変更する必要があるかもしれません。 動的ビットマップがアクセス・プランの中で使用されている場合は、 追加のソート・ヒープ・スペースが必要になります。 sheapthres が比較的、sortheap に近い (つまり、並行照会の割合が 2、3 回の係数よりも少ない) 場合、 複数索引アクセスに伴う動的ビットマップは、オプティマイザーが 想定した値よりずっと少ないメモリーで作動しなくてはなりません。これを解決するには、sheapthres の値を sortheap と比較して増加させます。

オプティマイザーは、単一の表にアクセスするのに、索引 ANDing 操作と索引 ORing 操作を組み合わせることはしません。

範囲がクラスター化された表での索引アクセス

標準的な表とは異なり、(従来の B ツリー索引のような) 行にキー値をマップする物理索引は、範囲がクラスター化された表には不要です。 その代わりに、列ドメインが持つ順次性を利用し、表内の特定の行の位置を生成するために関数マッピングを使用します。 このタイプのマッピングの最も単純な例では、範囲の最初のキー値は表の最初の行となり、 範囲の 2 番目の値は表の 2 番目の行となり、それ以降も同様になります。

オプティマイザーは表の範囲クラスター・プロパティーを使用し、完全にクラスター化された索引に基づいてアクセス・プランを生成します。その際のコストは範囲クラスター関数の計算だけです。 範囲がクラスター化された表には元のキー値配列が保持されるので、表内の行のクラスター化は保証されます。

カラム・オーガナイズ表での索引アクセス

カラム・オーガナイズ表にユニーク索引があると、その表の 1 つの行だけに作用する選択操作、更新操作、または削除操作のパフォーマンスを改善できます。これは、照会オプティマイザーが完全表スキャンの代わりに索引スキャンを使用できるためです。

カラム・オーガナイズ表にアクセスして返される行が 1 つだけの場合には、索引を使用して表にアクセスできます。以下のどちらかの条件が真である場合、索引アクセスによって複数の行が返されることはありません。
  • 索引がユニーク索引として定義されており、定数値と等価の述部が索引の各キー列に適用されること。
  • SQL ステートメントに FETCH FIRST 1 ROW ONLY 節が指定されていて、索引スキャン中にこのオプションを適用できること。
カラム・オーガナイズ表で明示的に索引を作成することはできませんが、ユニーク索引により、主キーまたはユニーク・キー制約が課せられます。 以下の条件が真である場合、パフォーマンスを改善するために、カラム・オーガナイズ表で主キーまたはユニーク・キー制約を作成できます。
  • 表データが真にユニークであること。
  • 表に対するワークロードが、固有列で 1 つの行だけに作用する選択操作、更新操作、または削除操作を頻繁に行うこと。
  • 1 つの行だけに作用する選択操作、更新操作、または削除操作で参照されている列に、主キー制約またはユニーク制約が存在していないこと。
DB2® Cancun リリース 10.5.0.4 以降のフィックスパックには、分離レベル CS (カーソル固定) で実行される SELECT ステートメントの索引アクセス・サポートが含まれています。さらに、1 つの表につき 1 つの行だけを参照する更新操作または削除操作 (行はユニーク制約を完全に修飾する等価述部によって識別される) のパフォーマンスは、主キーまたはユニーク・キー制約をサポートするユニーク索引を使用することによって向上させることができます。 ステートメントが以下の基準を満たしている場合、単一行の更新または削除に必要な時間を短縮できます。
  • 索引スキャンによって、最大 1 行が生成される。
  • FETCH 操作を必要としない (これは、アクセスが索引専用アクセスでなければならないことを意味します)。
  • 単一行を修飾する述部をすべて、索引検索の開始キー値または停止キー値として適用できる。
  • 索引アクセスから更新操作または削除操作へのパスは非中断パスでなければならない (これは、TEMP、SORT、HSJN などのブロック操作をパスに含めることができないことを意味します)。
例えば、ユニーク索引 PK が列 C1 に存在し、ユニーク索引 UK2 が列 (C1、C2) に存在しているとします。 DELETE 直下に CTQ 演算子が存在しないということは、この最適化が発生していることを示しています。
delete from t1
  where c1 = 99

             Rows
            RETURN
            (   1)
             Cost
              I/O
               |
               1
            DELETE
            (   2)
            16.3893
               2
         /----+-----\
        1            1000
     IXSCAN   CO-TABLE: BLUUSER
     (   3)           T1
     9.10425          Q1
        |
        1 
      1000
INDEX: BLUUSER
       UK2
       Q2