MySQL 8.0 リファレンスマニュアル MySQL NDB Cluster 8.0 を含む

このページは機械翻訳したものです。

8.10.3 プリペアドステートメントおよびストアドプログラムのキャッシュ

セッション中にクライアントが複数回実行する可能性がある特定のステートメントに対し、サーバーはステートメントを内部構造に変換し、実行時にその構造が使用されるようにキャッシュします。 キャッシュによって、セッション中にそれが再度必要になった場合に、ステートメントを再変換するオーバーヘッドが避けられるため、サーバーはより効率的に実行できます。 変換とキャッシュは、次のステートメントに対して行われます。

サーバーは、セッション単位でプリペアドステートメントおよびストアドプログラム用のキャッシュを保守します。 1 つのセッションでキャッシュされたステートメントは、ほかのセッションからアクセスできません。 セッションが終了すると、サーバーはそのためにキャッシュされたすべてのステートメントを破棄します。

サーバーがキャッシュされた内部ステートメント構造を使用する場合、構造が古くなっていないことに注意する必要があります。 ステートメントによって使用されているオブジェクトにメタデータの変更があり、現在のオブジェクト定義と内部ステートメント構造で表されている定義に不一致が発生することがあります。 メタデータの変更は、テーブルの作成、削除、変更、名前変更、切り捨てを行う DDL ステートメントや、テーブルの解析、最適化、修復を行う DDL ステートメントなどに対して発生します。 テーブルの内容の変更 (INSERTUPDATE などによる) ではメタデータが変更されず、SELECT ステートメントも変更されません。

次にこの問題を説明します。 クライアントがこのステートメントを準備するとします。

PREPARE s1 FROM 'SELECT * FROM t1';

SELECT * は内部構造からテーブル内のカラムのリストに展開します。 テーブル内のカラムのセットが ALTER TABLE によって変更されている場合、プリペアドステートメントが古くなります。 クライアントが次回 s1 を実行したときにサーバーがこの変更を検出しない場合、プリペアドステートメントは誤った結果を返します。

プリペアドステートメントによって参照されているテーブルやビューのメタデータの変更に原因がある問題を避けるため、サーバーはこれらの変更を検出し、次回の実行時にステートメントを自動的に再準備します。 つまり、サーバーはステートメントを再解析し、内部構造を再構築します。 再解析は、キャッシュ内に新しいエントリのための空きを作るために暗黙的に、または FLUSH TABLES によって明示的に、参照されているテーブルやビューがテーブル定義キャッシュからフラッシュされたあとにも行われます。

同様に、ストアドプログラムによって使用されているオブジェクトに変更が発生した場合、サーバーはプログラム内の影響のあるステートメントを再解析します。

サーバーは式内のオブジェクトのメタデータの変更も検出します。 これらは、DECLARE CURSOR などのストアドプログラムに固有のステートメントや IFCASE、および RETURN などのフロー制御ステートメントで使用できます。

ストアドプログラム全体の再解析を避けるため、サーバーは必要に応じて、プログラム内の影響のあるステートメントや式のみを再解析します。 例:

再解析では、元の内部形式への変換に有効であったデフォルトのデータベースと SQL モードが使われます。

サーバーは最大 3 回再解析を試みます。 すべての試みが失敗した場合、エラーが発生します。

再解析は自動ですが、それが行われた場合、プリペアドステートメントとストアドプログラムのパフォーマンスが低下します。

プリペアドステートメントの場合、Com_stmt_reprepare ステータス変数が再準備の数を追跡します。