ここでは、PREPAREの構文、パラメーター、および例を紹介します。
説明
PREPARE
は準備済みステートメントを作成します。 準備されたステートメントは、パフォーマンスを最適化するために使用できるサーバー側のオブジェクトです。 PREPARE
ステートメントが実行されると、指定されたステートメントが解析、分析、および書き換えられます。 その後、EXECUTE
コマンドが発行されると、準備されたステートメントが計画および実行されます。 この分業は、実行計画が供給された特定のパラメータ値に依存することを可能にしながら、反復的な構文解析作業を回避する。
準備されたステートメントは、実行されたときにステートメントに代入される値を取ることができます。 準備されたステートメントを作成するときは、$1
、$2
などを使用して、位置ごとにパラメーターを参照してください。 パラメータデータ型の対応するリストは、オプションで指定できます。 パラメーターのデータ型が指定されていないか、unknown
として宣言されている場合、パラメーターが最初に参照されたコンテキストから型が推論されます (可能な場合) 。 ステートメントを実行するときは、EXECUTE
ステートメントでこれらのパラメーターの実際の値を指定します。
準備されたステートメントは、現在のデータベースセッションの期間だけ続きます。 セッションが終了すると、準備されたステートメントは忘れられるため、再度使用する前に再作成する必要があります。 これは、単一の準備されたステートメントを複数の同時データベースクライアントで使用することはできませんが、各クライアントは独自の準備されたステートメントを作成して使用できます。 準備済みのステートメントは、DEALLOCATE
コマンドを使用して手動でクリーンアップできます。
準備されたステートメントは、単一のセッションが多数の同様のステートメントを実行するために使用されている場合に、最大のパフォーマンス上の利点を持つ可能性があります。 性能の差は、ステートメントが計画または書き直すのに複雑である場合、たとえば、クエリが多くのテーブルの結合を含む場合、またはいくつかのルールの適用を必要とする場合、特に重要である。 ステートメントの計画および書き換えが比較的簡単であるが、実行に比較的費用がかかる場合、準備されたステートメントのパフォーマンスの利点は目立たなくなります。
概要
PREPARE name [ ( data_type [, ...] ) ] ASステートメント
パラメーター
name
: この特定の準備されたステートメントに付けられた任意の名前。 単一のセッション内で一意である必要があり、その後、以前に準備したステートメントを実行または割り当て解除するために使用されます。data_type
: 準備されたステートメントのパラメーターのデータ型。 特定のパラメーターのデータ型が指定されていないか、unknown
として指定されている場合、パラメーターが最初に参照されたコンテキストから推測されます。 準備されたステートメント自体のパラメータを参照するには、$1
、$2
などを使用します。statement
:SELECT
、INSERT
、UPDATE
、DELETE
、またはVALUES
ステートメント。
注
準備されたステートメントは、一般的なプランまたはacustomプランのいずれかで実行できます。 汎用プランはすべての実行で同じですが、カスタムプランはその呼び出しで指定されたパラメーター値を使用して特定の実行に対して生成されます。 汎用プランの使用は、計画のオーバーヘッドを回避するが、状況によっては、プランナがパラメータ値の知識を利用することができるので、カスタムプランの実行がはるかに効率的になる。 (もちろん、準備されたステートメントにパラメータがない場合、これは議論の余地があり、一般的な計画が常に使用されます。)
既定では (つまり、plan_cache_mode
がauto
に設定されている場合) 、サーバーはパラメーターを持つ準備済みのステートメントに対してジェネリックプランを使用するかカスタムプランを使用するかを自動的に選択します。 このための現在のルールは、最初の5つの実行がカスタムプランで行われ、それらのプランの平均推定コストが計算されることです。 次に、汎用プランが作成され、その推定コストが平均カスタムプランコストと比較されます。 その後の実行では、そのコストが平均カスタムプランのコストよりもそれほど高くない場合に一般プランを使用して、繰り返し再計画を行うことが望ましいと思われます。
このヒューリスティックは、plan_cache_mode
をそれぞれforce_generic_plan
またはforce_custom_plan
に設定することで、サーバーにジェネリックプランまたはカスタムプランのいずれかを使用させるようにオーバーライドできます。 この設定は、汎用プランのコスト見積もりが何らかの理由で大きく外れている場合に主に役立ち、実際のコストがカスタムプランのコストよりもはるかに高い場合でも選択できます。
準備済みのステートメントにPolarDBが使用しているクエリプランを調べるには、EXPLAIN
を使用します。
EXPLAIN EXECUTE名 (parameter_values);
汎用プランが使用されている場合、パラメーターシンボル $
が含まれ、カスタムプランには指定されたパラメーター値が代入されます。
準備されたステートメントの主なポイントは、繰り返しの解析分析とステートメントの計画を回避することですが、PolarDBは、ステートメントで使用されるデータベースオブジェクトが定義 (DDL) の変更を受けた場合、または準備されたステートメントの以前の使用以降にプランナー統計が更新された場合、ステートメントを使用する前にステートメントの再分析と再計画を強制します。 また、search_pathの値が使用ごとに変更された場合、ステートメントは新しいsearch_path
を使用して再解析されます。 (この後者の動作は、PostgreSQL 9.3の新しいものです。) これらのルールは、同じクエリテキストを何度も再提出することと意味的にほぼ同等の準備されたステートメントを使用しますが、オブジェクト定義が変更されない場合、特に最良の計画が使用ごとに同じままである場合、パフォーマンスの利点があります。 意味的等価性が完全でない場合の例は、ステートメントが非修飾名によってテーブルを参照し、次いで同じ名前の新しいテーブルがsearch_path
の前に現れるスキーマ内に作成される場合、ステートメント内で使用されるオブジェクトが変更されないので、自動再解析が行われないことである。 ただし、他の何らかの変更によって再解析が強制される場合、新しいテーブルはその後の使用で参照されます。
pg_prepared_statements
システムビューをクエリすることで、セッションで使用可能な準備済みのすべてのステートメントを確認できます。
例
INSERT
ステートメントの準備済みステートメントを作成し、それを実行します。
PREPARE fooplan (int、text、bool、numeric) AS
INSERT INTO foo VALUES($1、$2、$3、$4);
EXECUTE fooplan(1、「ハンターバレー」、「t」、200.00);
SELECT
ステートメントの準備済みステートメントを作成し、それを実行します。
準備usrrptplan (int) AS
SELECT * ユーザーからu, logs l WHER E u.us rid=$1 AN D u.us ri d=l.us rid
AND l.date = $2;
EXECUTE usrrptplan(1, current_date);
この例では、2番目のパラメーターのデータ型は指定されていないため、$2
が使用されているコンテキストから推測されます。