Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

凍結プラン

ほとんどの SQL 文には、クエリ・プランが関連付けられています。SQL 文が準備されるときにクエリ・プランが作成されます。既定では、インデックスの追加やクラスのリコンパイルなどの操作によってこのクエリ・プランは削除されます。次回にクエリが呼び出されたときに、クエリが再準備され、新しいクエリ・プランが作成されます。凍結プランにより、コンパイルの前後で既存のクエリ・プランを維持 (凍結) できます。クエリの実行では、新しい最適化を実行したり、新しいクエリ・プランを生成したりするのではなく、凍結プランが使用されます。

システム・ソフトウェアに変更を加えた結果、クエリ・プランも異なるものになる可能性があります。通常、こういったアップグレードによって、クエリのパフォーマンスが向上しますが、ソフトウェアのアップグレードが特定のクエリのパフォーマンスを低下させる可能性もあります。凍結プランでは、クエリ・プランを維持 (凍結) できるので、システム・ソフトウェアのアップグレードによってクエリのパフォーマンスが変化 (低下または向上) することはありません。

凍結プランの使用方法

凍結プランの使用方法には、楽観的方法と悲観的方法という 2 つの方法があります。

  • 楽観的:この方法は、システム・ソフトウェアまたはクラス定義への変更でパフォーマンスが向上することを想定している場合に使用します。クエリを実行して、プランを凍結します凍結プランをエクスポート (バックアップ) しますプランの凍結を解除します。ソフトウェアに変更を加えます。クエリを再実行してください。これにより、新しいプランが生成されます。2 つのクエリのパフォーマンスを比較します。新しいプランではパフォーマンスが向上しない場合は、バックアップ・ファイルから以前の凍結プランをインポートします

  • 悲観的:この方法は、システム・ソフトウェアまたはクラス定義への変更で特定のクエリのパフォーマンスが向上する可能性がほとんどないことを想定している場合に使用します。クエリを実行して、プランを凍結します。ソフトウェアに変更を加えます。%NOFPLAN キーワードを指定してクエリを再実行します (凍結プランは無視されます)。2 つのクエリのパフォーマンスを比較します。凍結プランを無視してもパフォーマンスが向上しない場合は、プランを凍結したままにして、クエリから %NOFPLAN を削除します。

Caché バージョンのアップグレードによる自動的なプランの凍結

Caché を新しいメジャー・バージョンにアップグレードするときに、既存のクエリ・プランは自動的に凍結されます。これにより、ソフトウェアのメジャー・アップグレードによって既存のクエリのパフォーマンスが低下することがなくなります。ソフトウェア・バージョンのアップグレード後、パフォーマンスが重要なクエリについて以下の手順を実行します。

  1. プランの状態を [凍結/アップグレード] としてクエリを実行し、パフォーマンスを監視します。これは、ソフトウェアのアップグレード前に作成された、最適化されたクエリ・プランです。

  2. %NOFPLAN キーワードをクエリに追加して実行し、パフォーマンスを監視します。これにより、ソフトウェアのアップグレードで提供された SQL オプティマイザを使用して、クエリ・プランが最適化されます。既存のクエリ・プランの凍結は解除されません。

  3. パフォーマンス・メトリックを比較します。

    • %NOFPLAN のパフォーマンスが優れている場合、ソフトウェアのアップグレードによってクエリ・プランの効率が向上しています。クエリ・プランの凍結を解除します。%NOFPLAN キーワードを削除します。

    • %NOFPLAN のパフォーマンスが劣る場合、ソフトウェアのアップグレードによってクエリ・プランの効率が低下しています。クエリ・プランを凍結したままにします。[凍結/アップグレード] から [凍結/明示的] に昇格します。%NOFPLAN キーワードを削除します。

  4. パフォーマンスが重要なクエリをテストしたら、残りの [凍結/アップグレード] のプランすべての凍結を解除できます。

この自動凍結は、プランが最初に作成されたときの Caché バージョンよりも新しいバージョンでクエリを準備/コンパイルするときに実施されます。例えば、Caché バージョン 2016.2 で準備/コンパイルされた SQL 文について考えてみます。Caché をバージョン 2017.1 にアップグレードしてから、その SQL 文の準備/コンパイルを再実行します。システムは、これが新しいバージョンで実施されるその SQL 文の最初の準備/コンパイルになることを検出し、そのプランに自動的に [凍結/アップグレード] のマークを付けて、今回の準備/コンパイルに既存のプランを使用します。これにより、前のバージョンのクエリ・プランと同程度のクエリ・プランが使用されるようになります。

既存のクエリ・プランは、Caché のメジャー・バージョン・アップグレードでのみ自動的に凍結されます。この処理は、2016.2.0 以降からのアップグレードで実行されます。例えば、この処理は、2016.2 から 2017.1、または 2017.1 から 2017.2 などのメジャー・バージョン・アップグレードで実行されます。メンテナンス・リリースのバージョン・アップグレード (例えば、2017.1.0 から 2017.1.1) では、この処理は実行されません。

管理ポータルの SQL インタフェースの [SQL 文] にある [プランの状態] 列では、これに該当する自動的に凍結されたプランが [凍結/アップグレード] として示されます。また、[プランのバージョン] には、元のプランの Caché バージョンが示されます。詳細は、"SQL 文の詳細" を参照してください。このインタフェースを使用すると、個々のプランの凍結を解除できます。

1 つのプランまたは複数のプランを凍結または凍結解除する場合は、FreezePlans()Opens in a new tab メソッドを使用できます。

  • FreezePlans() を使用すると、ネームスペース、スキーマ、リレーション (テーブル)、個々のクエリなどの指定した範囲内の [凍結/アップグレード] クエリ・プランを凍結解除できます。

  • FreezePlans() を使用すると、[凍結/アップグレード] としてフラグが設定されたクエリ・プランを [凍結/明示的] に昇格 ("凍結") することもできます。一般に、このメソッドは適切な [凍結/アップグレード] プランを選択的に [凍結/明示的] に昇格してから、それ以外の [凍結/アップグレード] プランの凍結をすべて解除するために使用します。

Note:

Caché バージョン 2016.2 からそれ以降のバージョンにアップグレードする場合は、INSERT ... SELECT クエリ・プランが [凍結/アップグレード] に変更されることはありません。このプランの状態が [未凍結] であった場合、それらの文のプランの状態は [未凍結] のままになります。このプランの状態が [凍結] であった場合、そのプランはエラー状態になって使用できなくなります。このプランは明示的に凍結を解除する必要があります。アップグレード後に、INSERT ... SELECT 文を含んでいるコンテナ・コード (ルーチン、クラス) をリコンパイルするか、クエリ・キャッシュを削除してから再度準備する必要があります。その後で、以前に凍結されていたプランを必要に応じて再凍結します。

凍結プランのインタフェース

凍結プランのインタフェースは 2 つあり、それぞれに用途が異なります。

  • 管理ポータルの [SQL 文] インタフェースは、個別のクエリのプランを凍結 (または凍結解除) する場合に使用します。

  • $SYSTEM.SQL.FreezePlans() メソッド・インタフェースは、ネームスペース、スキーマ、テーブル、または個々のクエリに対するプランをすべて凍結または凍結解除する場合に使用します。

管理ポータルの SQL インタフェースで、[クエリ実行] タブを選択します。クエリを作成してから、[プラン表示] ボタンをクリックして現在のクエリ実行プランを表示します。プランが凍結されている場合、[クエリプラン] セクションの先頭行は "Frozen Plan" です。

管理ポータル SQL インタフェースで、[SQL 文] タブを選択します。SQL 文のリストが表示されます。このリストの [プランの状態] 列には、[未凍結]、[未凍結/並列]、[凍結/明示的]、または [凍結/アップグレード] が示されます ([プランの状態] 列は、文に関連付けられているクエリ・プランがない場合は空欄になります)。

プランを凍結または凍結解除するには、[SQL 文テキスト] 列で SQL 文を選択します。[SQL 文の詳細] ボックスを表示します。このボックスの下側に、[文テキストとクエリ・プラン] が表示されます。これらのセクションの背景色は、プランが凍結されていない場合は緑色、プランが凍結されている場合は青色になります。そのすぐ上側にある [文のアクション] では、目的に合わせて [プランの凍結] ボタンまたは [プランの凍結解除] ボタンを選択できます。その後で、[閉じる] を選択します。

  • [プランの凍結] ボタン:このボタンをクリックすると、この文のクエリ最適化プランが凍結されます。プランが凍結されているときに、その SQL 文をコンパイルすると、SQL コンパイルは凍結プランの情報を使用して、クエリ最適化フェーズを省略します。

  • [プランの凍結解除] ボタン:ボタンをクリックすると、この文の凍結プランが削除され、この文の新しいコンパイルではクエリ最適化フェーズを完了して、使用に最適なプランが決定されます。

1 つ以上のプランの凍結または凍結解除には、FreezePlans()Opens in a new tab メソッドを使用することもできます。ネームスペース、SQL スキーマ名、SQL スキーマ.テーブル名、SQL 文ハッシュ値で指定されたクエリ・プラン文のいずれかを指定することによって、凍結または凍結解除操作の範囲を指定できます。

[SQL 文の詳細] ボックス内にあるその他の各フィールドの用途と使用法は、このドキュメントの “SQL 文” の章を参照してください。

特権

ユーザは、EXECUTE 特権を持っている SQL 文のみを表示できます。これは、管理ポータルの [SQL 文] リストと INFORMATION_SCHEMA.STATEMENTS クラスのクエリの両方に当てはまります。

管理ポータルの [SQL 文] にアクセスするには、%Development リソースに対する "USE" 特権が必要になります。管理ポータルで SQL 文を表示できるユーザは、その SQL 文を凍結または凍結解除できます。

SQL 文へのカタログ・アクセスの場合は、文を実行する特権が付与されているか、%Development リソースに対する "USE" 特権を持っている場合に文を表示できます。

$SYSTEM.SQL.FreezePlan() メソッド呼び出しの場合は、%Developer リソースに対する "U" 特権を持っている必要があります。

凍結プランの相違

プランが凍結されている場合は、実際にプランの凍結を解除することなく、プランの凍結を解除したときに異なるプランが生成されるかどうかを判断できます。この情報は、プランの凍結を解除した場合にパフォーマンスが向上するかどうかを判断するために、%NOFPLAN を使用してテストする価値がある SQL 文を決定する際に役立ちます。

凍結プランは、以下のいずれかの操作によって現在のクエリ・プランとは異なるものになる可能性があります。

リコンパイルによって、既存のクエリ・キャッシュが自動的に削除されます。その他の操作では、新しいクエリ・プランを適用するには、既存のクエリ・キャッシュを手動で削除する必要があります。

これらの操作によってクエリ・プランが異なるものになるかどうかはわかりません。以下の 2 つの方法で、その結果を判断できます。

  • 個別の凍結プランの手動チェック

  • すべての凍結プランの自動日次スキャン

これらのどちらかの方法でプランがチェックされていない場合や、プランが凍結されていない場合は、[SQL 文] リストの [新規プラン] 列は空欄になります。チェック済みの凍結プランの凍結を解除すると、[新規プラン] 列は空欄にリセットされます。

凍結プランの手動チェック

凍結プランの [SQL 文の詳細] ページの上側に、[凍結のチェック] ボタンがあります。このボタンをクリックすると、[未凍結プランの相違] チェック・ボックスが表示されます。このボックスにチェックが付いている場合は、プランの凍結を解除すると異なるクエリ・プランが生成されます。

この [凍結のチェック] テストを凍結プランに対して実行すると以下のようになります。

  • [未凍結プランの相違] ボックスにチェックが付いている場合は、[SQL 文] リストの [新規プラン] 列の内容が "1" になります。これは、プランの凍結を解除すると異なるプランが生成されることを意味します。

  • [未凍結プランの相違] ボックスにチェックが付いていない場合は、[SQL 文] リストの [新規プラン] 列の内容が "0" になります。これは、プランの凍結を解除しても異なるプランが生成されないことを意味します。

    • 凍結されているクエリ・キャッシュ[新規プラン] は "0" になっています。クエリ・キャッシュを削除してプランの凍結を解除すると、SQL 文は表示されなくなります。

    • 凍結されているナチュラル・クエリ[新規プラン] 列は空欄になっています。

[凍結のチェック] ボタンは、このテストの実行後に表示されなくなります。凍結プランの再テストが必要な場合は、[ページの更新] ボタンをクリックします。これにより、[凍結のチェック] ボタンが再度表示されます。

凍結プランの自動日次チェック

Caché SQL は、[SQL 文] リストにある凍結されたすべての文を毎晩午前 2:00 時に自動的にスキャンします。このスキャンは最大で 1 時間かかります。スキャンが 1 時間で完了しなかった場合、Caché は中断した場所を記録して、そこから次回の日次スキャンを続行します。管理ポータルを使用して、この日次スキャンを監視したり、直ちにスキャンするよう強制したりできます。[システム操作][タスクマネージャ][タスクスケジュール] の順に選択してから、Scan frozen plans タスクを選択します。

このスキャンでは、すべての凍結プランを以下のように検査します。

  • 凍結プランの Caché バージョンが現在のバージョンと同じ場合、Caché は、このプランが参照するすべてのテーブルと、それらのテーブルのタイムスタンプに対するハッシュを計算します。これらのいずれかが変更されている場合、[SQL 文] リストの [新規プラン] 列を "1" にして SQL 文にフラグを設定します。これは、プランの凍結を解除すると、異なるクエリ・プランが生成されることを意味します。

  • 凍結プランの Caché バージョンが現在のバージョンと同じで、テーブルのタイムスタンプが変化していない場合、[SQL 文] リストの [新規プラン] 列を "0" にして SQL 文にフラグを設定します。これは、プランの凍結を解除しても異なるクエリ・プランが生成されないことを意味します。

  • 凍結プランの Caché バージョンと現在のバージョンが異なる場合 (凍結/更新)、Caché は、SQL オプティマイザのロジックを変更すると異なるクエリ・プランが生成されるかどうかを判断します。異なるクエリ・プランが生成される場合は、[SQL 文] リストの [新規プラン] 列を "1" にして SQL 文にフラグを設定します。異なるクエリ・プランは生成されない場合は、[新規プラン] 列を "0" にして SQL 文にフラグを設定します。

このスキャンの結果は、INFORMATION_SCHEMA.STATEMENTS を呼び出すことによって確認できます。以下の例では、すべての凍結プランの 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 と表示されます。

クエリがコンパイル (またはリコンパイル) されるときに、凍結プランがエラー状態の場合、Caché は凍結プランを使用しません。代わりに、現在の定義で動作する新しいクエリ・プランが作成されます。ただし、このクエリ・プランは、凍結プランが実施されているときには、クエリ・キャッシュや SQL 文に保存されません。

エラー状態のプランは、プランの凍結が解除されるか、プランが有効な状態に戻るように定義を変更するまでエラー状態のままになります。

プランが有効な状態に戻るように定義を変更した場合は、[SQL 文の詳細] ページに移動し、[エラーのクリア] ボタンをクリックして、エラーが修正されたかどうかを確認します。修正されている場合は、[プラン・エラー] フィールドが表示されなくなります。それ以外の場合は、[プラン・エラー] のメッセージが再表示されます。定義が修正されている場合は、明示的にプラン・エラーをクリアしなくても、Caché は凍結プランを使用するようになります。定義が修正されている場合は、[エラーのクリア] ボタンにより、[SQL 文の詳細] ページの [凍結クエリ・プラン] エリアに、実行プランが再度表示されます。

[プラン・エラー] は、"ソフト・エラー" の可能性があります。これは、プランがインデックスを使用していて、そのインデックスの選択可能性が SetMapSelectability()Opens in a new tab で 0 に設定されているために、現時点ではクエリ・オプティマイザが選択できない場合に発生することがあります。ほとんどの場合、この原因はインデックスが構築 (再構築) されたことによります。凍結プランがある文に Caché がソフト・エラーを検出すると、クエリ・プロセッサは自動的にエラーのクリアを試行して、凍結プランを使用します。プランがエラー状態のままの場合は、そのプランに再度エラー状態のマークが付けられ、クエリ実行は使用可能な最適なプランを使用するようになります。

%NOFPLAN キーワード

%NOFPLAN キーワードを使用すると、凍結プランをオーバーライドできます。%NOFPLAN キーワードを含んでいる SQL 文は、新しいクエリ・プランを生成します。凍結プランは保持されますが、使用されません。これにより、凍結プランを維持しながら、生成されたプランの動作をテストできるようになります。

%NOFPLAN の構文は、以下のとおりです。

DECLARE <cursor name> CURSOR FOR SELECT %NOFPLAN ... 
SELECT %NOFPLAN .... 
INSERT [OR UPDATE] %NOFPLAN ... 
DELETE %NOFPLAN ... 
UPDATE %NOFPLAN 

SELECT 文では、クエリ内で最初の SELECT の直後にのみ %NOFPLAN キーワードを使用できます。これは、UNION クエリの最初の項にのみ使用可能であり、サブクエリでは使用できません。%NOFPLAN キーワードは、SELECT の直後 (DISTINCT や TOP など、その他のキーワードより前) に配置する必要があります。

凍結プランのエクスポートとインポート

SQL 文はエクスポートすることも、インポートすることもできます。これにより、凍結プランを別の場所に移動できます。SQL 文のエクスポートとインポートには、関連付けられているクエリ・プランが含まれます。

SQL 文をファイルにエクスポートするには、ExportSQLStatement()Opens in a new tab メソッドを使用します。

このネームスペース内の SQL 文をすべてファイルにエクスポートするには、ExportAllSQLStatements()Opens in a new tab メソッドを使用します。

1 つまたは複数の SQL 文をファイルからインポートするには、ImportSQLStatement()Opens in a new tab メソッドを使用します。

FeedbackOpens in a new tab