ほとんどの SQL 文には、クエリ・プランが関連付けられています。クエリ・プランは、SQL 文が準備されるときに作成されます。既定で、インデックスの追加やクラスのリコンパイルなどの操作によってこのクエリ・プランは削除されます。次回にクエリが呼び出されたときに、クエリが再準備され、新しいクエリ・プランが作成されます。凍結プランにより、コンパイルの前後で既存のクエリ・プランを維持 (凍結) できます。クエリの実行で、新しい最適化を実行して新しいクエリ・プランを生成するのではなく、凍結プランが使用されるようになります。
システム・ソフトウェアへの変更によって、別のクエリ・プランが作成される場合もあります。通常、こういったアップグレードにより、クエリ・パフォーマンスが向上しますが、ソフトウェアのアップグレードによって特定のクエリのパフォーマンスが低下する場合があります。凍結プランを使用すると、クエリ・プランを維持 (凍結) して、クエリ・パフォーマンスがシステム・ソフトウェアのアップグレードによって変化 (低下または向上) しないようにすることができます。
ソフトウェアのバージョンをアップグレードした後の凍結プラン
InterSystems IRIS® のデータ・プラットフォームを新しいメジャー・バージョンにアップグレードすると、既定では既存のクエリ・プランは自動的に凍結されます。つまり、ソフトウェアのメジャー・アップグレードによって既存のクエリのパフォーマンスが低下することがあります。ソフトウェアのバージョンをアップグレードする前に、パフォーマンスが重要なクエリをすべて手動で凍結することを検討します。アップグレード後に、これらのクエリに以下の手順を実行します。
-
プランの状態を [凍結/明示] としてクエリを実行し、パフォーマンスを監視します。これは、プランを明示的に凍結する前に作成した最適化済みクエリ・プランです。
-
%NOFPLAN キーワードをクエリに追加して実行し、パフォーマンスを監視します。これにより、ソフトウェアのアップグレードで提供された SQL オプティマイザを使用して、クエリ・プランが最適化されます。既存のクエリ・プランの凍結は解除されません。
-
パフォーマンス・メトリックを比較します。
-
%NOFPLAN のパフォーマンスが優れている場合、ソフトウェアのアップグレードによってクエリ・プランの効率が向上しています。クエリ・プランの凍結を解除します。%NOFPLAN キーワードを削除します。
-
%NOFPLAN のパフォーマンスが劣る場合、ソフトウェアのアップグレードによってクエリ・プランの効率が低下しています。クエリ・プランを凍結状態のままとして、%NOFPLAN キーワードを削除します。
-
パフォーマンスが重要なクエリのテストが終了すれば、凍結した残りのプランをすべて凍結解除してもかまいません。
自動凍結を有効にしている場合は、プランを作成した InterSystems ソフトウェアよりも新しいバージョンのソフトウェアでクエリを準備またはコンパイルしたときに自動凍結が実行されます。例えば、システム・ソフトウェア・バージョン xxxx.1 で準備またはコンパイルした SQL 文を考えます。その後でバージョン xxxx.2 にアップグレードし、その SQL 文を再び準備/コンパイルします。システムは、これが新しいバージョンで実施されるその SQL 文の最初の準備/コンパイルになることを検出し、そのプランに自動的に [凍結/アップグレード] のマークを付けて、今回の準備/コンパイルに既存のプランを使用します。これにより、前のバージョンのクエリ・プランと同程度のクエリ・プランが使用されるようになります。
メジャー・バージョンの InterSystems システム・ソフトウェアのアップグレードでのみ、既存のクエリ・プランが自動的に凍結されます。メンテナンス・リリース・バージョンのアップグレードでは、既存のクエリ・プランは凍結されません。例えば、2018.1 から 2019.1 などのようなメジャー・バージョンのアップグレードでこの処理が実行されます。2018.1.0 から 2018.1.1 などのようなメンテナンス・リリース・バージョンのアップグレードでは、この処理は実行されません。
INFORMATION.SCHEMA.STATEMENTSOpens in a new tab Frozen=2 プロパティを使用して、現在のネームスペースの凍結/アップグレード・プランをすべてリスト表示できます。
次の $SYSTEM.SQL.Statement メソッドを使用して 1 つのクエリ・プランまたは複数のクエリ・プランを凍結できます : 1 つのプランの場合は FreezeStatement()Opens in a new tab、関係のすべてのプランの場合は FreezeRelation()Opens in a new tab、スキーマのすべてのプランの場合は FreezeSchema()Opens in a new tab、現在のネームスペースのすべてのプランの場合は FreezeAll()Opens in a new tab。対応する Unfreeze メソッドがあります。
-
Freeze メソッドを使用すると、[凍結/アップグレード] としてフラグが設定されたクエリ・プランを [凍結/明示] に昇格 ("凍結") できます。一般に、このメソッドは適切な [凍結/アップグレード] プランを選択的に [凍結/明示的] に昇格してから、それ以外の [凍結/アップグレード] プランの凍結をすべて解除するために使用します。
-
Unfreeze メソッドを使用すると、ネームスペース、スキーマ、リレーション (テーブル)、または個々のクエリといった指定した範囲内での [凍結/アップグレード] クエリ・プランを凍結解除できます。
凍結プランのインタフェース
FREEZE PLANS コマンドを使用してクエリを凍結でき、UNFREEZE PLANS コマンドを使用してクエリを凍結解除できます。どちらの操作も、テーブル別、スキーマ別、またはネームスペース別に個別のクエリに対して実行できます。個別のプランを凍結または凍結解除するには、INFORMATION_SCHEMA.STATEMENTS をクエリすることにより、目的の Statement の Hash を探し出します。つづいて、FREEZE PLANS または UNFREEZE PLANS を使用して、特定の文の Hash を指定することで、その文のプランの状態を変更できます。
Frozen プロパティに対して INFORMATION_SCHEMA.STATEMENTS をクエリすることで、現在のネームスペースにあるすべての SQL 文のプランの状態を一覧できます。Frozen 列の値は、凍結解除 (0)、凍結/明示 (1)、凍結/アップグレード (2)、または未凍結/パラレル (3) のいずれかです。特定のクエリに EXPLAIN を使用して、そのクエリが凍結状態であるかどうかを判断することもできます。
1 つ以上のプランの凍結または凍結解除には、$SYSTEM.SQL.Statement Freeze および Unfreeze メソッドを使用することもできます。次の適切なメソッドを指定して、凍結または凍結解除操作の範囲を指定できます : 1 つのプランの場合は FreezeStatement()Opens in a new tab、関係のすべてのプランの場合は FreezeRelation()Opens in a new tab、スキーマのすべてのプランの場合は FreezeSchema()Opens in a new tab、現在のネームスペースのすべてのプランの場合は FreezeAll()Opens in a new tab。対応する Unfreeze メソッドがあります。
特権
ユーザは、INFORMATION.SCHEMA.STATEMENTSOpens in a new tab クラス・クエリなど、自身が EXECUTE 特権を持っている SQL 文のみを表示できます。SQL 文へのカタログ・アクセスの場合は、文を実行する特権が付与されているか、%Development リソースに対する "USE" 特権を持っている場合に文を表示できます。
$SYSTEM.SQL.Statement Freeze または Unfreeze メソッド呼び出しの場合は、%Developer リソースに対する "U" 特権を持っている必要があります。
管理ポータルの [SQL 文] にアクセスするには、%Development リソースに対する "USE" 特権が必要です。管理ポータルで SQL 文を表示できるユーザは、その SQL 文を凍結または凍結解除できます。
凍結プランの相違
プランが凍結されている場合は、実際にプランの凍結を解除することなく、プランの凍結を解除したときに異なるプランが生成されるかどうかを判断できます。この情報は、プランの凍結を解除した場合にパフォーマンスが向上するかどうかを判断するために、%NOFPLAN を使用してテストする価値がある SQL 文を決定する際に役立ちます。
INFORMATION.SCHEMA.STATEMENTSOpens in a new tab FrozenDifferent プロパティを使用して、現在のネームスペースのこのタイプの凍結プランをすべてリスト表示できます。
凍結プランは、以下のいずれかの操作によって現在のプランとは異なるものになる可能性があります。
リコンパイルによって、既存のクエリ・キャッシュが自動的に削除されます。その他の操作の場合に新規クエリ・プランを適用するには、既存のクエリ・キャッシュを手動で削除する必要があります。
これらの操作によってクエリ・プランが異なるものになるかどうかはわかりません。すべての凍結プランをスキャンして、新しいクエリ・プランが生成されるかどうかを判断できます。
凍結プランの自動日次チェック
InterSystems SQL は、[SQL 文] リストにある凍結されたすべての文を毎晩午前 2:00 時に自動的にスキャンします。このスキャンは最大で 1 時間かかります。スキャンが 1 時間で完了しなかった場合は、中断した場所が記録され、そこから次回の日時スキャンが続行されます。
さらに、管理ポータルを使用してスキャンを強制実行できます。そのためには、[システムオペレーション]→[タスクマネージャ]→[タスクスケジュール] の順に選択し、Scan frozen plans タスクを選択します。
このスキャンの結果は、INFORMATION.SCHEMA.STATEMENTSOpens in a new tab を呼び出すことで確認できます。以下の例では、すべての凍結プランの SQL 文が返され、凍結されない場合になるプランと凍結プランが異なるかどうかが示されます。未凍結プランの場合の文は Frozen=0 または Frozen=3 となる可能性があることに注意してください。
SELECT Frozen,FrozenDifferent,Timestamp,Statement FROM INFORMATION_SCHEMA.STATEMENTS
WHERE Frozen=1 OR Frozen=2
エラー状態の凍結プラン
文のプランが凍結されているときに、そのプランに使用している定義に何らかの変更を加えることでプランが無効になると、エラーが発生します。例えば、文のプランに使用していたクラスからインデックスが削除されたとします。
-
文のプランは凍結された状態を維持します。
-
[SQL 文の詳細] ページの [コンパイル設定] エリアに、[プラン・エラー] フィールドが表示されます。例えば、クエリ・プランで indxdob というインデックス名が使用されていた場合、インデックス indxdob を削除するようにクラス定義を変更すると、次のようなメッセージが表示されます:Map 'indxdob' not defined in table 'Sample.Mytable', but it was specified in the frozen plan for the query.
-
[SQL 文の詳細] ページの [クエリプラン] エリアには、Plan could not be determined due to an error in the frozen plan と表示されます。
凍結プランがエラー状態の間にクエリが再実行された場合、InterSystems IRIS は凍結プランを使用しません。代わりに、現在の定義で動作する新しいクエリ・プランが作成されて、そのクエリが実行されます。このクエリ・プランには、前のクエリ・プランと同じクエリ・キャッシュ・クラス名が割り当てられます。
エラー状態のプランは、プランの凍結が解除されるか、プランが有効な状態に戻るように定義を変更するまでエラー状態のままになります。
プランが有効な状態に戻るように定義を変更した場合は、[SQL 文の詳細] ページに移動し、[エラーのクリア] ボタンをクリックして、エラーが修正されたかどうかを確認します。修正されている場合は、[プラン・エラー] フィールドが表示されなくなります。それ以外の場合は、[プラン・エラー] のメッセージが再表示されます。定義が修正されている場合は、明示的にプラン・エラーをクリアしなくても、SQL は凍結プランを使用するようになります。定義が修正されている場合は、[エラーのクリア] ボタンにより、[SQL 文の詳細] ページの [凍結クエリ・プラン] エリアに、実行プランが再度表示されます。
[プラン・エラー] は、"ソフト・エラー" の可能性があります。これは、プランがインデックスを使用していて、そのインデックスの選択可能性が SetMapSelectability()Opens in a new tab で 0 に設定されているために、現時点ではクエリ・オプティマイザが選択できない場合に発生することがあります。ほとんどの場合、この原因はインデックスが構築 (再構築) されたことによります。凍結プランがある文に InterSystems IRIS がソフト・エラーを検出すると、クエリ・プロセッサは自動的にエラーをクリアして、凍結プランを使用しようとします。プランがエラー状態のままの場合は、そのプランに再度エラー状態のマークが付けられ、クエリ実行は使用可能な最適なプランを使用するようになります。