パラメータ化クエリのプラン ガイドの設計
パラメータ化されたクエリに対してプラン ガイドを作成できます。クエリのパラメータ化は、次のいずれかの理由で行います。
sp_executesql を使用してクエリを送信する。
強制パラメータ化がデータベースで有効になっている。これにより、すべての適格なクエリがパラメータ化されます。
このクエリが属しているクエリのクラスに別のプラン ガイドを作成し、パラメータ化を指定した。
パラメータ化クエリのプラン ガイドを作成するときは、すべてのクエリに対して基本的に同じ形式にパラメータ化するためのプラン ガイドを作成します。ただし、定数リテラル値だけは異なります。たとえば、強制パラメータ化が有効になっているデータベースでは、次の 2 つのクエリは同じ形式にパラメータ化されます。
SELECT pi.ProductID, SUM(pi.Quantity) AS Total
FROM Production.ProductModel pm INNER JOIN Production.ProductInventory pi ON pm.ProductModelID = pi.ProductID
WHERE pi.ProductID = 101
GROUP BY pi.ProductID, pi.Quantity
HAVING sum(pi.Quantity) > 50;
SELECT pi.ProductID, SUM(pi.Quantity) AS Total
FROM Production.ProductModel pm INNER JOIN Production.ProductInventory pi ON pm.ProductModelID = pi.ProductID
WHERE pi.ProductID = 101
GROUP BY pi.ProductID, pi.Quantity
HAVING sum(pi.Quantity) > 50;
SELECT pi.ProductID, SUM(pi.Quantity) AS Total
FROM Production.ProductModel pm INNER JOIN Production.ProductInventory pi ON pm.ProductModelID = pi.ProductID
WHERE pi.ProductID = 101
GROUP BY pi.ProductID, pi.Quantity
HAVING sum(pi.Quantity) > 100;
SELECT pi.ProductID, SUM(pi.Quantity) AS Total
FROM Production.ProductModel pm INNER JOIN Production.ProductInventory pi ON pm.ProductModelID = pi.ProductID
WHERE pi.ProductID = 101
GROUP BY pi.ProductID, pi.Quantity
HAVING sum(pi.Quantity) > 100;
パラメータ化クエリのプラン ガイドを作成するには、SQL 型のプラン ガイドを作成します。その際、sp_create_plan_guide ストアド プロシージャにクエリのパラメータ化形式を指定します。
たとえば、上記の例のいずれかのクエリのパラメータ化形式を取得し、ハッシュ結合の使用をオプティマイザに強制するプラン ガイドを作成するには、次の手順を実行します。
sp_get_query_template を実行して、クエリのパラメータ化形式を取得します。
sp_executesql または PARAMETERIZATION FORCED データベース SET オプションを使用して、SQL Server でクエリがまだパラメータ化されていない場合は、パラメータ化を強制するために TEMPLATE 型のプラン ガイドを作成します。
パラメータ化クエリの SQL 型のプラン ガイドを作成します。
次のバッチを使用すると、これらの 3 つのすべての手順を実行できます。
--Obtain the paramaterized form of the query:
DECLARE @stmt nvarchar(max);
DECLARE @params nvarchar(max);
EXEC sp_get_query_template N'SELECT pi.ProductID, SUM(pi.Quantity) AS Total
FROM Production.ProductModel pm
INNER JOIN Production.ProductInventory 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;
--Force parameterization of the query. (This step is only required
--if the query is not already being parameterized.)
EXEC sp_create_plan_guide N'TemplateGuide1',
@stmt,
N'TEMPLATE',
NULL,
@params,
N'OPTION(PARAMETERIZATION FORCED)';
--Create a plan guide on the parameterized query
EXEC sp_create_plan_guide N'GeneralizedGuide1',
@stmt,
N'SQL',
NULL,
@params,
N'OPTION(HASH JOIN)';
--Obtain the paramaterized form of the query:
DECLARE @stmt nvarchar(max);
DECLARE @params nvarchar(max);
EXEC sp_get_query_template N'SELECT pi.ProductID, SUM(pi.Quantity) AS Total
FROM Production.ProductModel pm
INNER JOIN Production.ProductInventory 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;
--Force parameterization of the query. (This step is only required
--if the query is not already being parameterized.)
EXEC sp_create_plan_guide N'TemplateGuide1',
@stmt,
N'TEMPLATE',
NULL,
@params,
N'OPTION(PARAMETERIZATION FORCED)';
--Create a plan guide on the parameterized query
EXEC sp_create_plan_guide N'GeneralizedGuide1',
@stmt,
N'SQL',
NULL,
@params,
N'OPTION(HASH JOIN)';
これでプラン ガイドは、指定した形式にパラメータ化されるすべてクエリに適用されますが、含まれる定数リテラル値は異なります。