準備実行

適用対象: SQL Server Azure SQL データベース Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW)

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)