Hitachi

ノンストップデータベース HiRDB Version 10 UAP開発ガイド


4.1.3 インデクス検索時の留意事項

この項では,インデクスの変更(データの変更に伴うインデクスのメンテナンス処理)の内部動作,及びインデクス検索時のUAPの設計指針について説明します。

インデクスは,探索条件に対する行の絞り込みを効率的に行い,データに対するアクセスや検索結果の返却を高速に行うためのアクセス手段です。

HiRDBは,複数のトランザクションによるインデクス検索と,インデクスの変更を同時に行うことによって,高レスポンス,高スループットのシステムを実現しています。しかし,その反面,インデクス変更の最中にインデクスを使用した検索を行うと,検索結果が変わることがあります。検索結果を変えないために,検索時に検索対象の表に対して排他を掛ける(LOCK TABLE文を実行する)対処方法がありますが,システムの性能要件からこの対処方法が適用できないケースもあります。

このような場合に,複数トランザクションを同時実行し,順序関係に厳密な業務アプリケーションを実行するときは,この項で説明するUAPの設計指針を参考に業務アプリケーションを開発してください。

また,複数列インデクスを構成する列(例えば,ステータスの列など)に対する更新時のインデクス検索についても注意が必要です。

〈この項の構成〉

(1) インデクス変更の内部動作

インデクス構成列の列値変更(UPDATE文)に伴うインデクスの変更は,更新前の列値に対応するインデクスエントリの変更処理,及び更新後の列値に対応するインデクスエントリの変更処理の,二つの処理によって実現します。

ここでの更新前の列値に対応するインデクスエントリの変更とは,対応するインデクスキーがある行データが一つの場合,インデクスキーの削除を示します。更新後の列値に対応するインデクスエントリの変更とは,対応するインデクスキーがある行データが一つの場合,インデクスキーの追加を示します。また,これらの処理をインデクスキーの削除,インデクスキーの追加の順に実行します。これは,インデクスの変更時にインデクス容量の増加を抑えるためです。

インデクス変更の内部動作の例を次の図に示します。

図4‒1 インデクス変更の内部動作の例

[図データ]

[説明]

インデクスを定義している列をBからKに更新するトランザクションが実行します。

まず,1で更新トランザクションが更新前の列値に対応するインデクスキーBを削除します。

その後,2で更新後の列値に対応するインデクスキーKを追加します。

(2) インデクス検索時の検索結果

インデクスの変更の最中にインデクス検索を行うと,検索結果が変わるケースがあります。具体的には,次の二つのケースがあります。

(a) 更新中の行が検索対象外となる

更新中の行が検索対象外となるケースについて説明します。

■ インデクス検索が終了していない範囲から,終了した範囲へのインデクス更新

UPDATE文によって,インデクス検索が終了していない範囲から,終了した範囲へインデクスキーを更新すると,そのインデクスキーは検索対象外となります。

更新中の行が検索対象外となる例を次の図に示します。

図4‒2 更新中の行が検索対象外となる例(その1)

[図データ]

[説明]

インデクスを定義している列をKからDに更新するトランザクションと,インデクスを検索するトランザクションが同時に実行します。

インデクス検索は,1〜3でキーJに対する検索まで終了しています。

キーKを検索する時点で,更新トランザクションが4でキーKを削除,5でキーDを追加するため,対応する行は検索対象外となります。

[補足]

インデクス検索の探索条件がインデクスキー全体(複数列インデクスの場合,すべての構成列に対する探索条件)の場合,検索対象行がUPDATE文によって探索条件から外れるため問題はありません。ただし,複数列インデクスで変更列以外の構成列に対する列を探索条件とした場合,業務によっては問題となるおそれがあります。この場合の対処方法については,「UAPの設計指針」を参照してください。

■ インデクス検索が終了した範囲へのインデクスキー追加

インデクス検索より先にINSERT文を実行しても,インデクス検索が終了した範囲へインデクスキーを追加すると,そのインデクスキーは検索対象外となります。

更新中の行が検索対象外となる例を次の図に示します。

図4‒3 更新中の行が検索対象外となる例(その2)

[図データ]

[説明]

インデクスを定義している列がDの行を追加するトランザクションと,インデクスを検索するトランザクションが同時に実行します。

HiRDB内部の変更タイミングとして,更新トランザクションが4でキーDを追加する時点で,既にインデクス検索は3でキーJに対する検索まで終了しています。結果として,追加されたキーDに対応する行は検索対象外となります。

[補足]

更新中の行が検索対象外となるために,データ操作に対して順序関係の厳密さを必要とする業務によっては問題となるおそれがあります。この場合の対処方法については,「UAPの設計指針」を参照してください。

■ UPDATE文に伴うインデクスキーの変更

インデクスの変更の際,インデクスキーを削除した時点でインデクス検索が行われた場合,対応する行は検索対象外となります。

更新中の行が検索対象外となる例を次の図に示します。

図4‒4 更新中の行が検索対象外となる例(その3)

[図データ]

[説明]

インデクスを定義している列の値をDからEに更新するトランザクションと,インデクス検索を行うトランザクションが同時に実行します。

更新トランザクションが1でキーDを削除した時点で,検索トランザクションは2でキーB,3でキーCの検索を終了しています。このため,4でのキーEの追加に対応する行は,検索対象外となります。

[補足]
  • 更新前のインデクスキーと,更新後のインデクスキーが同じ場合,インデクスの変更は行いません。ただし,次のどれかの条件を満たす場合は,インデクスの変更(インデクスキーの削除及び追加)を行います。

    ・定義長256バイト以上の可変長文字列型の列を構成列に持つインデクス

    ・繰返し列を構成列に持つインデクス

    ・部分構造インデクス

  • インデクス検索の探索条件がインデクスキー全体の場合,検索対象行がUPDATE文によって探索条件から外れるため問題はありません。ただし,複数列インデクスで変更列以外の構成列に対する列を探索条件とした場合,業務によっては問題となるおそれがあります。UPDATE文に伴うインデクスキーの変更によって検索されなくなる例を次の図に示します。

    図4‒5 UPDATE文に伴うインデクスキーの変更によって検索されなくなる例

    [図データ]

[説明]

商品コード104の商品が100個入荷されたので,在庫数に100を加算します。

SCODE,SNAME,及びZSURYOで構成される複数列インデクスを利用して検索します。この場合,1で更新中の行は検索対象にならないため,検索結果に含まれません。

この場合の対処方法については「UAPの設計指針」を参照してください。

(b) 更新対象の行が複数回検索結果に現れる

更新対象の行が複数回検索結果に現れるケースについて説明します。

■ インデクス検索が終了した範囲から,終了していない範囲へのインデクス更新

排他オプションにWITHOUT LOCK WAITを指定した場合,トランザクション完了までの検索結果は保証されないため,タイミングによって更新対象の行が検索結果として複数回現れることがあります。排他オプションにWITHOUT LOCK NOWAITを指定した場合も同様です。具体的には,UPDATE文によってインデクス検索が終了した範囲から,終了していない範囲へインデクスキーを更新すると,そのインデクスキーは再度検索されます。

更新対象の行が複数回検索結果に現れる例を次の図に示します。

図4‒6 更新対象の行が複数回検索結果に現れる例

[図データ]

[説明]

インデクスを定義している列をBからKに更新するトランザクションと,インデクスを検索するトランザクションが同時に実行します。

1でキーBを検索する時点で,排他オプションの指定によって排他が解除されているため,更新トランザクションは対応行を更新できます。

検索トランザクションが5でキーJを検索する前に,更新トランザクションが対応行を更新(3でのキーBの削除,及び4でのキーKの追加)したため,6でのキーKの検索によって,対応する更新行が検索結果に2回現れます。

[補足]

統計情報など,厳密さを必要としないデータの検索結果として扱う場合は問題ありませんが,検索結果がその後の業務処理に影響を及ぼすような厳密さを必要とする場合は,問題となるおそれがあります。この場合の対処方法については,「UAPの設計指針」を参照してください。

(3) インデクス検索の動作

INSERT文,UPDATE文,及びDELETE文実行中にインデクスを検索した場合,検索結果が変わるケースが発生する可能性を,次の表に示します。

表4‒1 検索結果が変わるケースが発生する可能性

後続処理(インデクスを使用した検索)

先行処理

INSERT文

UPDATE文

DELETE文

SELECT文

×

×

UPDATE文

×

×

DELETE文

×

×

(凡例)

○:検索結果は変わりません。

×:検索結果が変わる(検索対象外となる)可能性があります。

注※

排他オプションWITHOUT LOCK WAIT又はWITHOUT LOCK NOWAITの場合,更新対象の行が複数回検索結果に現れる可能性があります。

INSERT文ではインデクスを使用した検索は行わないため,後続処理としてINSERT文で発生する可能性はありません。

なお,更新対象の行が複数回検索結果に現れるかどうかは,更新前後のインデクスキー値の変化に依存します。更新トランザクションがインデクスを更新したときの,インデクスキー値の変化の方向と,検索トランザクションのインデクス検索方向が一致する場合,次に示す表のように,複数回検索結果に現れる可能性があります。

インデクス検索方向

UPDATE文によるインデクスキー値の変化

インデクスキー値が大きくなる

インデクスキー値が小さくなる

インデクスキー値が同じ(同値更新)

昇順

(キー値の大きい方向)

×

降順

(キー値の小さい方向)

×

(凡例)

○:検索結果は変わりません。

×:検索結果が変わる(複数回検索結果に現れる)可能性があります。

(4) UAPの設計指針

複数トランザクションを同時に実行する場合で,順序関係に厳密さを必要とする業務アプリケーションを開発するときは,UAPが表に対する排他を取得することで,インデクスの変更とインデクス検索をシリアライズする必要があります。ただし,性能面で影響がある場合には,次の対処を検討してください。

  1. インデクス構成列に更新項目を含めないようにしてください。

  2. 検索頻度,条件などでインデクス構成列に更新項目を含めなければならない場合は,更新項目以外のインデクス構成列を探索条件としたインデクス検索で,業務上の問題が発生しないかどうか確認してください。問題が発生する場合には,その探索条件でこのインデクスを検索に使用しないようにしてください。

  3. 2.が採用できない場合は,UAPで検索結果に対する再チェック処理を組み込んでください。