-1

特定のパラメータに対して実行速度が非常に遅いストアド プロシージャがあります。

ストアド プロシージャはデータセットを返しました。

ストアド プロシージャをビューに変換しました。同じパラメーターと値を宣言すると、数秒でデータセットが返されます。

ストアド プロシージャには 5 分かかります。

問題をストアド プロシージャの特定のサブクエリに絞り込みました。サブクエリを削除すると、ストアド プロシージャがデータをすぐに返すことができるようになりました。サブクエリを一時テーブルに変換し、サブクエリではなく一時テーブルに結合したところ、ストアド プロシージャは数秒でデータを返すようになりました。

操作は、最初のビューとストアド プロシージャ テストで同じでした。ビューの実行方法に違いはありますか?

新しい一時テーブルを使用したスト​​アド プロシージャを次に示します。元のサブクエリはコメント アウトされています。

 (@JCCo bCompany,  
  @BegContract bContract ='', 
  @EndContract bContract ='zzzzzzzzzz', 
  @ThruMth bDate,
  @PM int = 0,
  @LabCTs varchar(10)=null,
  @MatCTs varchar(10)=null,
  @BegDept varchar(10) ='', 
  @EndDept varchar(10) ='zzzzzzzzzz')


With Recompile
as
--move the dates into a temp table
Select JCJM.JCCo, JCJM.Contract, JCCD.Job,
                        LastLaborDate=max(Case when JCTransType='PR' and (CostType between 2 and 3) then ActualDate else null end),
                        LastProjCostDate=max(Case when JCTransType='PF' then ActualDate else null end)
                    INTO #DATES
                   From JCCD JCCD with(NoLock)
                   Join JCJM JCJM with(nolock) on JCJM.JCCo=JCCD.JCCo and JCJM.Job=JCCD.Job
                    where (JCTransType='PR' or JCTransType='PF') and JCCD.JCCo=@JCCo and JCCD.Mth<=@ThruMth 
                            and JCJM.Contract Between @BegContract and @EndContract
                    group by JCJM.JCCo,JCJM.Contract,JCCD.Job
      -- ) as Dates on j.JCCo=Dates.JCCo and j.Contract=Dates.Contract and j.Job=Dates.Job




Select  JCCD.JCCo, JCCD.Job, JobDesc=j.Description, b.Contract, ContrDesc=b.Description, 

    --  MAX(Dates.LastLaborDate) as maxLastLaborDate, MAX(Dates.LastProjCostDate) as maxLastProjCostDate, 
    TD.LastLaborDate, TD.LastProjCostDate, 
--      '01/01/2013' AS LastLaborDate, '01/01/2015' AS LastProjCostDate,

        JCCD.Mth, JCCD.Phase, PhsDesc=JCJP.Description, 
        JCCD.CostType, CTDesc=JCCT.Description, JCCT.JBCostTypeCategory, 
        FieldPctCompl=isnull(u.PctCompl,0), FieldDate=Max(u.Date),  PMName=p.Name, 
        EstHours=sum(EstHours), EstCost=sum(EstCost), JTDHrs=sum(ActualHours), JTDCost=sum(ActualCost),
        ProjHours=sum(JCCD.ProjHours), ProjCost=sum(JCCD.ProjCost),
        MTDHrs=sum(case when JCCD.Mth=@ThruMth then ActualHours else 0 end), 
        MTDCost=sum(case when JCCD.Mth=@ThruMth then ActualCost else 0 end),
        FActCost=SUM(Case when JCCO.ProjMethod=2 then JCCD.ActualCost+JCCD.RemainCmtdCost else JCCD.ActualCost end),
        b.Department, DeptDesc=d.Description, HQName=HQCO.Name,ContrStat=b.ContractStatus,UIAmt=0,UITaxAmt=0,UIMiscAmt=0,ToBeInvd=0,sumTotalCmtdCost=0

from JCCD JCCD with(NoLock)
Left Outer Join JCJM j with(NoLock) on JCCD.JCCo=j.JCCo and JCCD.Job=j.Job
Left Outer Join JCCM b with(NoLock) on j.JCCo=b.JCCo and j.Contract=b.Contract
Left Outer Join JCDM d with(noLock) on b.JCCo=d.JCCo and b.Department=d.Department
Left Outer Join JCMP p with(NoLock) on j.JCCo=p.JCCo and j.ProjectMgr=p.ProjectMgr
Left Outer Join JCJP JCJP with(NoLock) on JCCD.JCCo=JCJP.JCCo and JCCD.Job=JCJP.Job and JCCD.Phase=JCJP.Phase
Left Outer Join JCCT JCCT with(NoLock) on JCCD.PhaseGroup=JCCT.PhaseGroup and JCCD.CostType=JCCT.CostType

Left Outer Join (Select u.Co, Job=u.Contract/*Prints Job# 9/13 per Tina - - VU9148*/, JCJM.Contract,
                        u.Phase, u.CostType, a.Mth, 
                        Date=Max(isnull(Date,'1950-01-01')),PctCompl=isnull(PctCompl,0)
                  from udVPPctComplete u
                  Join JCJM on u.Co=JCJM.JCCo and u.Contract=JCJM.Job
                  Join (select Co, Job=a.Contract,Contract=JCJM.Contract, Phase, CostType, Mth=Max(isnull(Mth,'1950-01-01')) 
                          from udVPPctComplete a 
                          Join JCJM on a.Co=JCJM.JCCo and a.Contract=JCJM.Job
                          where Mth<=@ThruMth and Co=@JCCo and JCJM.Contract between @BegContract and @EndContract
                          group by Co, a.Contract,JCJM.Contract, Phase, CostType
                     )a on a.Co=u.Co and a.Job=u.Contract and a.Phase=u.Phase and  a.CostType=u.CostType and a.Mth=u.Mth and a.Contract=JCJM.Contract
                group by u.Co, u.Contract,JCJM.Contract, u.Phase, u.CostType, a.Mth, isnull(PctCompl,0)
    ) u on JCCD.JCCo=u.Co and b.Contract=u.Contract and JCCD.Phase=u.Phase and JCCD.CostType=u.CostType and u.Job=JCCD.Job

    LEFT OUTER JOIN #DATES TD ON  j.JCCo=TD.JCCo and j.Contract=TD.Contract and j.Job=TD.Job
--Left Outer Join (Select JCJM.JCCo, JCJM.Contract, JCCD.Job,
--                      LastLaborDate=max(Case when JCTransType='PR' and (CostType between 2 and 3) then ActualDate else null end),
--                      LastProjCostDate=max(Case when JCTransType='PF' then ActualDate else null end)
--                 From JCCD JCCD with(NoLock)
--                 Join JCJM JCJM with(nolock) on JCJM.JCCo=JCCD.JCCo and JCJM.Job=JCCD.Job
--                  where (JCTransType='PR' or JCTransType='PF') and JCCD.JCCo=@JCCo and JCCD.Mth<=@ThruMth 
--                          and JCJM.Contract Between @BegContract and @EndContract
--                  group by JCJM.JCCo,JCJM.Contract,JCCD.Job
--     ) as Dates on j.JCCo=Dates.JCCo and j.Contract=Dates.Contract and j.Job=Dates.Job

Join JCCO JCCO with(NoLock) on JCCD.JCCo=JCCO.JCCo
Join HQCO HQCO with(NoLock) on JCCD.JCCo=HQCO.HQCo

where  JCCD.JCCo=@JCCo and b.Contract/*=' 51431.'--*/ between @BegContract and @EndContract and JCCD.Mth<=@ThruMth 
        and b.Department>=@BegDept and b.Department<=@EndDept 
        and j.ProjectMgr=(case when @PM<>0 then @PM else j.ProjectMgr end)

        and (charindex(','+left(cast(JCCD.CostType as char(5))+'     ', len(convert(varchar, JCCD.CostType)))+',', ','+@LabCTs+',')<>0 
                or charindex(','+left(cast(JCCD.CostType as char(5))+'     ', len(convert(varchar, JCCD.CostType)))+',', ','+@MatCTs+',')<>0 )
Group by JCCD.JCCo, JCCD.Job,j.Description, b.Contract, b.Description, JCCD.Mth, JCCD.Phase, JCJP.Description, JCCD.CostType,
            u.PctCompl,JCCT.Description, p.Name,JCCT.JBCostTypeCategory,
                    TD.LastLaborDate, TD.LastProjCostDate, 

            --Dates.LastLaborDate, Dates.LastProjCostDate,
            b.Department, 
            d.Description,HQCO.Name,b.ContractStatus
4

1 に答える 1

1

両方のクエリが文字通り同じである場合は、ストアド プロシージャに破損したクエリ プランがキャッシュされている可能性があります。

プロシージャに追加することで、毎回プランを再コンパイルするようにプロシージャを強制できOPTION(RECOMPILE)ます。

OPTION(RECOMPILE) のキム・トリップ

特定のステートメントが実行ごとに大きく変化し、最適な計画が変化することがわかっている場合 (繰り返しますが、複数のサンプル実行をテストすることでこれを知る必要があります)、ストアド プロシージャを通常どおりに作成し、OPTION (RECOMPILE) を使用します。ステートメントのプランがキャッシュされたり、ストアド プロシージャと共に保存されたりしないようにします。実行ごとに、そのストアド プロシージャは異なるパラメーターを取得し、特に厄介なステートメントは実行ごとに新しい計画を取得します。

編集今、あなたが再コンパイルを呼び出していることがわかりました。この回答はここに残しておきますが、他の検索者に関連する可能性があるためです。

于 2013-11-06T16:43:12.217 に答える