プラン ガイドを使用してクエリパラメーター化の動作を指定する

適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

PARAMETERIZATION データベース オプションを SIMPLE に設定すると、SQL Server クエリ オプティマイザーがクエリのパラメーター化を選択する場合があります。 このパラメーター化は、クエリ内のすべてのリテラル値をパラメーターに置き換えます。 この処理を簡易パラメーター化と呼びます。 SIMPLEパラメーター化が有効な場合、パラメーター化されるクエリとパラメーター化されないクエリを制御することはできません。 ただし、 PARAMETERIZATION データベース オプションを FORCED に設定することで、データベース内のすべてのクエリをパラメーター化するように指定できます。 この処理を強制パラメーター化と呼びます。

次のような方法でプラン ガイドを使用すると、データベースのパラメーター化の動作をオーバーライドできます。

オプション 説明
SIMPLE 特定のクラスのクエリで強制パラメーター化を試行することを指定できます。 そのためには、クエリのパラメーター化された形式で TEMPLATE プラン ガイドを作成し、PARAMETERIZATION FORCEDクエリ ヒントを指定します。 このようなプラン ガイドは、すべてのクエリではなく、ある種のクエリにのみパラメーター化を強制する方法と考えることができます。 詳細については、「 単純なパラメーター化」を参照してください。
FORCED 特定のクラスのクエリに対して、強制パラメーター化ではなく、単純なパラメーター化のみを実行することを指定できます。 これを行うには、クエリの強制パラメーター化された形式で TEMPLATE プラン ガイドを作成し、PARAMETERIZATION SIMPLEsp_create_plan_guideクエリ ヒントを指定します。 詳細については、「 強制パラメーター化」を参照してください。

AdventureWorks2025 データベースを対象とした次のクエリについて考えてみましょう。

SELECT pi.ProductID,
       SUM(pi.Quantity) AS Total
FROM Production.ProductModel AS pm
     INNER JOIN Production.ProductInventory AS pi
         ON pm.ProductModelID = pi.ProductID
WHERE pi.ProductID = 101
GROUP BY pi.ProductID, pi.Quantity
HAVING SUM(pi.Quantity) > 50;

データベース管理者は、データベース内のすべてのクエリに対して強制パラメーター化を有効にしないことを決定します。 ただし、前のクエリと構文的に同等であるが、定数リテラル値のみが異なるクエリでは、コンパイル コストを回避する必要があります。 つまり、クエリをパラメーター化し、この種のクエリのクエリ プランを再利用できるように考えています。 このような場合は、次の手順を実行します。

  1. パラメーター化された形式のクエリを取得します。 sp_create_plan_guideで使用するためにこの値を取得する唯一の安全な方法は、sp_get_query_template システム ストアド プロシージャを使用することです。

  2. PARAMETERIZATION FORCEDクエリ ヒントを指定して、クエリのパラメーター化された形式でプラン ガイドを作成します。

    重要

    SQL Server はクエリのパラメーター化処理の一環として、リテラルの値とサイズに従って、リテラル値を置き換えるパラメーターにデータ型を割り当てます。 同じプロセスが、@stmtsp_get_query_template出力パラメーターに渡される定数リテラルの値にも発生します。 @paramssp_create_plan_guide引数に指定されたデータ型は、SQL Serverによってパラメーター化されるため、クエリのデータ型と一致する必要があるため、クエリに使用できるパラメーター値の完全な範囲をカバーするために、複数のプラン ガイドを作成する必要がある場合があります。

次のスクリプトを使用すると、パラメーター化クエリの取得と、このクエリのプラン ガイドの作成の両方の処理を行えます。

DECLARE @stmt AS NVARCHAR (MAX);
DECLARE @params AS NVARCHAR (MAX);

EXECUTE sp_get_query_template
    N'SELECT pi.ProductID, SUM(pi.Quantity) AS Total
      FROM Production.ProductModel AS pm
      INNER JOIN Production.ProductInventory AS pi ON pm.ProductModelID = pi.ProductID
      WHERE pi.ProductID = 101
      GROUP BY pi.ProductID, pi.Quantity
      HAVING SUM(pi.Quantity) > 50',
@stmt OUTPUT, @params OUTPUT;

EXECUTE sp_create_plan_guide N'TemplateGuide1',
@stmt, N'TEMPLATE', NULL,
@params, N'OPTION(PARAMETERIZATION FORCED)';

データベースで強制パラメーター化が既に有効になっている場合は、特定のクエリに対してオーバーライドできます。 単純なパラメーター化規則に従ってサンプル クエリと構文上同等のクエリをパラメーター化するには、PARAMETERIZATION SIMPLE句でPARAMETERIZATION FORCEDの代わりにOPTIONを指定します。

TEMPLATE プラン ガイドは、ステートメントと、単一のステートメントのみで構成されるバッチにより送信されるクエリとを対応付けます。 複数ステートメント バッチ内のステートメントは、TEMPLATE プラン ガイドでは照合できません。