1

クエリの最適化後、問題のない結果が得られ、ストアドプロシージャを変更したかったのですが、SPの実行後は、クエリの実行後よりもはるかに悪い結果が得られました。

まず、読み取り回数で考えます。非常に異なる結果の理由は何でしょうか?

クエリはSPと同じですが、唯一の違いは、クエリでパラメータを宣言したことですが、SPでは入力パラメータでした。パラメータに設定される値も同じです。「記録されたデータ」を回避するために、最初にSPを再コンパイルし、その後DROPとCREATEを実行しましたが、結果も大きく異なりました。

クエリは次のようになります(簡略化のためにテーブルと列の名前が変更され、列の数が減ります):

DECLARE @Var1 varchar(20)    
SET @Var1 = @Var1 + '%'       

DECLARE @Var2 TIMESTAMP    
SELECT @Var2 = CONVERT(TIMESTAMP, ID, 0)    
FROM    
 X_TIMESTAMPS (NOLOCK)    
WHERE    
 TABLE = 'T1'     


declare @Var3 varbinary(8)    
SELECT @Var3 = max(IdTimeStamps)    
FROM    
 T1 (NOLOCK)     

SELECT o.c1  
  , o.c2   
  , o.c3    
  , v.c4    
  , v.c5   
  , p.c6    
  , p.c7    
  , va.c8    
  , isnull(s.c9, '') AS c9    
  , CASE o.c10    
     WHEN 1 THEN    
      0    
     ELSE    
      1    
    END c10   
  , o.c11    
FROM    
 T1 o (NOLOCK)    
 JOIN T2 p (NOLOCK)    
  ON o.c1 = p.c12    
 JOIN T3 i (NOLOCK)    
  ON (o.c13 = i.c14)    
 JOIN T4 v (NOLOCK)    
  ON (v.c4 = i.c15)    
 LEFT JOIN T5 s (NOLOCK)    
  ON (o.c16 = s.c17)    
 JOIN T6 va (NOLOCK)    
  ON o.c11 = va.c18    
WHERE    
 o.c1 LIKE @Var1    
 AND o.c2 > @Var2 

そして、手順は次のようになります。

CREATE PROCEDURE [dbo].[SP1] @Var1 varchar(20) ='' 
WITH RECOMPILE  
AS        
BEGIN

    PREVIOUS QUERY WITHOUT DECLARATION FOR @Var1

END

事前にTnX!

ネマンジャ

4

2 に答える 2

2

これは、定数を使用したクエリとパラメータを使用したspに異なる実行プランが使用されているためです。あなたはいくつかのトリックを試すことができます

インラインテーブル関数を作成して試してください

create function sf_test
(
    @param1 int
)
returns table
as
return
    your query using @in_param1

また

このようにプロシージャで追加のパラメータを宣言します

create procedure sp_test
(
    @param1 int
)
as
begin
    declare @in_param1 int

    select @in_param1 = @param1

    your query using @in_param1
end

プロシージャでオプションを使用してみるwith recompileか、動的SQLを使用することもできます

于 2012-10-22T11:26:30.957 に答える
2

これはほぼ確実にパラメータスニッフィングの問題です。個人的には、この問題を回避し、(この問題が発生した場合にのみ)入力パラメーターの値に設定される変数を作成するダミー変数オプションが好きでした。

于 2012-10-22T12:19:18.127 に答える