次の方法で共有


準備実行

ODBC API では、準備実行とは、Transact-SQL ステートメントを繰り返し実行する際に関連して生じる解析やコンパイルのオーバーヘッドを削減する方法と定義されています。 アプリケーションでは SQL ステートメントを保持する文字列を構築してから、そのステートメントを 2 段階に分けて実行します。 まず、SQLPrepare 関数 を 1 回呼び出すと、データベース エンジンでステートメントが解析され、実行プランにコンパイルされます。 次に、この準備された実行プランの各実行に対して SQLExecute を呼び出します。 この方法では、各実行にかかる解析とコンパイルのオーバーヘッドが抑制されます。 準備実行は、通常、同一のパラメーター化された SQL ステートメントを繰り返し実行するアプリケーションで使用されます。

ほとんどのデータベースでは、直接実行されるステートメントが実行のたびにコンパイルされるのに対し、準備実行されるステートメントは 1 回だけコンパイルされるので、準備実行は主に 4、5 回以上実行されるステートメントの場合は直接実行よりも高速になります。 準備実行では、SQL ステートメントが実行されるたびに、ドライバーはステートメント全体ではなく、実行プランの識別子とパラメーター値だけをデータ ソースに送信できるので、ネットワーク トラフィックも削減できます。

SQL Server では、SQLExecDirect が実行プランを検出し再利用するアルゴリズムが強化されたので、直接実行と準備実行のパフォーマンスの差異が少なくなります。 そのため、直接実行されるステートメントでも、準備実行のパフォーマンス上の利点の一部を利用できるようになります。 詳細については、「直接実行」を参照してください。

SQL Server では、準備実行がネイティブにサポートされます。 実行プランは SQLPrepare で構築され、その後 SQLExecute が呼び出されると実行されます。 SQL Server では、SQLPrepare で一時ストアド プロシージャを構築する必要がないので、tempdb のシステム テーブルに余分なオーバーヘッドがなくなります。

パフォーマンス上の理由から、SQLExecute が呼び出されるまで、またはメタプロパティ操作 (ODBC の SQLDescribeColSQLDescribeParam など) が実行されるまで、ステートメントの準備は遅延されます。 これは既定の動作です。 準備されているステートメントのエラーは、ステートメントまたはメタプロパティ操作が実行されるまでわかりません。 SQL Server Native Client ODBC ドライバー固有のステートメント属性の SQL_SOPT_SS_DEFER_PREPARE を SQL_DP_OFF に設定することで、この既定の動作を無効にできます。

準備が遅延されている場合、SQLExecute を呼び出す前に SQLDescribeCol または SQLDescribeParam のいずれかを呼び出すと、サーバーとの間に余分なやり取りが発生します。 SQLDescribeCol では、クエリが返す最初の結果セットの列の情報を取得するために、ドライバーはクエリから WHERE 句を削除し、SET FMTONLY ON を付加してサーバーに送信します。 SQLDescribeParam では、クエリのすべてのパラメーター マーカーで参照される式や列の情報を取得するために、ドライバーがサーバーを呼び出します。 この方法には、サブクエリのパラメーターを解決することができないなど、いくつか制限事項もあります。

SQL Server Native Client ODBC ドライバーで SQLPrepare を使いすぎると、特に以前のバージョンの SQL Server に接続している場合はパフォーマンスが低下します。 準備実行は、1 回しか実行されないステートメントには使用しないでください。 準備実行では、クライアントからサーバーへのネットワーク上のやり取りを余分に実行する必要があるため、ステートメントを 1 回しか実行しない場合は直接実行よりも時間がかかります。 以前のバージョンの SQL Server では、準備実行で一時ストアド プロシージャの生成も行います。

SQL Server では、準備されたステートメントを使用して一時オブジェクトを作成することはできません。

以前の ODBC アプリケーションでは、SQLBindParameter が使用されたときは必ず SQLPrepare を使用したものがありました。 SQLBindParameter では、SQLPrepare を使用する必要はなく、SQLExecDirect と併用できます。 たとえば、SQLBindParameterSQLExecDirect を併用して、1 回しか実行されないストアド プロシージャからリターン コードや出力パラメーターを取得します。 同じステートメントが複数回実行される場合以外は、SQLBindParameterSQLPrepare は併用しないでください。

関連項目

概念

ステートメントの実行 (ODBC)