PREPARE

名前

PREPARE -- 実行する文を準備する

概要

PREPARE name [ ( data_type [, ...] ) ] AS statement

説明

PREPAREは準備された文を作成します。 準備された文は、性能を最適化するために利用可能なサーバ側オブジェクトです。 PREPARE文を実行すると、指定された問い合わせの構文解析、書き換え、実行計画の作成が行われます。 その後、EXECUTE文が発行された際は、準備された文に必要な処理は実行のみになります。 このため、構文解析、書き換え、実行計画の作成が一度で済み、問い合わせが実行される度にこれらを行う必要がなくなります。

準備された文はパラメータ、すなわち文が実行される時に代入される値を取ることができます。 準備された文を作成する時には$1$2などを使用して、位置によりパラメータを参照してください。 省略可能ですが、対応するパラメータのデータ型のリストを指定することもできます。 パラメータのデータ型の指定がない、または、unknownと宣言されている場合、型はパラメータが使用される文脈より(可能ならば)推測されます。 文の実行時には、EXECUTE文内にこれらのパラメータの実際の値を指定します。 詳細はEXECUTEを参照してください。

準備された文は現在のデータベースセッションの期間中にのみ保持されます。 セッションが終了すると、準備された文は破棄されます。 そのため、再び利用する場合は、再作成する必要があります。 また、これは、1つの準備された文を複数のデータベースクライアントから使用することはできないことを意味します。 ただし、各クライアントが個別に準備された文を作成することはできます。 準備された文を手作業で削除するには、DEALLOCATEコマンドを使用します。

準備された文の利点を最大限に発揮できるのは、単一のセッションで同類の問い合わせを多数実行する場合です。 パフォーマンスの違いは、文の書き換えや実行計画が複雑なほど顕著になるでしょう。 例えば、問い合わせに多数のテーブルの結合が含まれている場合や、いくつものルールを適用しなければならない場合などが考えられます。 書き換えおよび実行計画が比較的単純で、実行コストが高い文の場合は、準備された文の効果はそれほど現れないでしょう。

パラメータ

name

個々の準備された文に与えられる任意の名前です。 この名前は、1つのセッション内で一意でなければいけません。準備された文の実行および削除の時に、この名前が使用されます。

data_type

準備された文に対するパラメータのデータ型です。 特定のパラメータのデータ型の指定がない、または、unknownと指定された場合、パラメータが使用される文脈から推測されます。 準備された文自体の中でこのパラメータを参照する時は、$1$2などを使用します。

statement

SELECTINSERTUPDATEDELETEVALUES文のいずれかです。

注釈

状況によっては、準備された文用に生成された問い合わせ計画が、普通に送信され実行された場合の問い合わせ計画よりも劣ってしまう場合があります。 これは、実行計画を作成する際、プランナが最適な問い合わせ計画を判断するために、文の中で指定されたパラメータの実際の値を使用できないことが原因です。 PostgreSQLでは、テーブル内のデータ分布に関する統計を取り、文中の定数を使って問い合わせの実行結果を予測しています。 パラメータを持つ準備された文の実行計画を作成する場合は、このようなデータを使用できないため、選択された計画が最適ではない可能性があります。 PostgreSQLが準備された文に対して選択した問い合わせ計画を検査するには、EXPLAINを使用してください。

問い合わせの実行計画や問い合わせの最適化のためにPostgreSQLが収集する統計に関する詳細は、ANALYZEのドキュメントを参照してください。

pg_prepared_statementsシステムビューを問い合わせることによりセッションで利用可能な準備された文をすべて確認することができます。

INSERT文に対して準備された文を作成し、実行します。

PREPARE fooplan (int, text, bool, numeric) AS
    INSERT INTO foo VALUES($1, $2, $3, $4);
EXECUTE fooplan(1, 'Hunter Valley', 't', 200.00);

SELECT文に対して準備された文を作成し、実行します。

PREPARE usrrptplan (int) AS
    SELECT * FROM users u, logs l WHERE u.usrid=$1 AND u.usrid=l.usrid
    AND l.date = $2;
EXECUTE usrrptplan(1, current_date);

第2パラメータのデータ型が指定されていないことに注目してください。 このため$2が使用される文脈からデータ型が推測されます。

互換性

標準SQLにはPREPARE文が含まれていますが、埋め込みSQLでの使用に限られています。 また、標準SQLのPREPARE文では多少異なる構文が使用されます。

関連項目

DEALLOCATE, EXECUTE