記事
· 2024年2月29日 3m read

インデックス再構築が終わるまで新しく定義したインデックスを使用させない方法

これは InterSystems FAQ サイトの記事です。

新しいインデックスを定義した後、インデックスの再構築が完了する前にクエリを実行するとデータが存在しているにもかかわらず「検索結果0件」や検索結果数が徐々に増えるような状況が発生します。

インデックスを永続クラス定義(またはテーブル定義)に追加しコンパイルすることで今まで使用していたクエリ実行経路が削除され、再度同じクエリを実行するタイミングで新しいインデックス定義を含めた実行経路が作成されるためです。(この時にインデックス再構築が完了していないとインデックスデータが存在しない、または不完全であるため0件や徐々に検索結果数が増えるような状況を起こします。)

これを起こさなために、新しいインデックスの再構築が終了するまでクエリオプティマイザにインデックスを使用させないように指定する方法が用意されています。

※インデックスの再構築が完了したら、必ず指定を元に戻してください。

2022.1以降では、$SYSTEM.SQL.Util.SetMapSelectability()を使用します。

(2021.1以前では、$SYSTEM.SQL.SetMapSelectability()を使用します。引数の指定方法は2022.1以降と同様です。)

 

SetMapSelectability()メソッドは%Statusの戻り値が設定されています。
ステータスOKの場合は1が戻ります。エラーステータスの場合は以下のメソッドを使用してエラー内容を確認してください。

write $SYSTEM.Status.GetErrorText(ステータスが入った変数)

ご参考:%Statusのエラーが返ってきたら

 

以下、Training.Employeeに新インデックス:NewIndexを定義する例でご紹介します。

1) 定義予定の新インデックス名をクエリオプティマイザが使用しないように設定します。

set status=$SYSTEM.SQL.Util.SetMapSelectability("Training.Employee","NewIndex",0)
  • 第1引数:クラス名
  • 第2引数:インデックス名(これから指定する新インデックス名を指定します。)
  • 第3引数:隠す場合は0、見せる場合は1

2) インデックスを追加します。

  • 永続クラスの場合はインデックスを追加しコンパイルし、インデックス再構築を実行します。
  • SQL文で実行する場合はCREATE INDEXを実行した後インデックス再構築が自動的に開始されます。

3) クエリオプティマイザにインデックスを見せるように変更します。

 ※インデックスの再構築が終了してから行います。

$system.SQL.Util.SetMapSelectability("Training.Employee","NewIndex",1)

4) クエリキャッシュを削除します。

 管理ポータルでクエリキャッシュを削除するには、管理ポータル > [システムエクスプローラ] > [SQL] > (対象ネームスペースに切り替えた後) > [アクション] > [クエリキャッシュ削除]

プログラムからキャッシュを破棄する場合は、「プログラムでクエリキャッシュを削除する方法」をご参照ください。

関連項目として、インデックスの再構築を複数のプロセスで行う方法もあります。
詳細は:「アプリケーション使用中にインデックス再構築を複数プロセスで実行する方法」をご覧ください。 

《注意》CREATE INDEX文でインデックスを追加した場合、インデックス追加後すぐに再構築が開始されますが、インデックスをクラス定義文で追加した場合インデックス再構築は実行を命令するまで開始されません。

ディスカッション (0)1
続けるにはログインするか新規登録を行ってください