0

次のクエリを最適化して、特に結合のパフォーマンスを向上させようとしています。提案や助けをいただければ幸いです。どうもありがとう。サブクエリの代わりに CTE を使用することを考えています

クエリ:

Select  year(dtb.tbDATE) as YearR, 
     `CONVERT(VARCHAR(12),dtb.tbDATE,110) as DateR,
     (case when dtb.l_grp_no= 7 then COMPANY_B else COMPANY_A end ) as Portfolio,
     (case when dtb.past_days between 5 and 30 then '5-30'
          when dtb.past_days between 31 and 60  then'31-60'
          when dtb.past_days between 61 and 90  then '61-90'
          when dtb.past_days >= 91 then '91+' 
          when dtb.past_days <5 then 'Current' else 'Dis_po' end) 'Qdel',
     case when lsc.SStatusC is not null and dtb.tbDATE> ls.eff_date 
          then lsc.SStatusC else 'XX'end as 'LStatus',
     count(dtb.refaccno) as lcount,
     sum (dtb.P_bal) as Lbal
from sln.[dbo].[table_dtb] as dtb
     --left outer join sln.dbo.acct_l la on dtb.accrefno = la.accrefno
     left outer join (select stat_acct_l.* from sln.dbo.stat_acct_l
     inner join 
         (select refaccno, max(row_id) as MaxRow_id
          from sln.dbo.stat_acct_l
          group by refaccno) as maxStatus 
        on stat_acct_l.refaccno = maxStatus.refaccno 
            and stat_acct_l.row_id = maxStatus.MaxRow_id) as ls 
        on ls.refaccno = dtb.refaccno
     left outer join dw.dbo.AccSt_C lsc on lsc.Stat_C_ID= ls.status_code_no
where dtb.l_grp_no in (7,4,8,15)and dtb.tbDATE > '2010-06-31'
     and dtb.P_bal+dtb.l_C_bal >0
group by year(dtb.tbDATE), CONVERT(VARCHAR(12),dtb.tbDATE,110),
     case when dtb.past_days between 5 and 30 then '5-30'
          when dtb.past_days between 31 and 60  then'31-60'
          when dtb.past_days between 61 and 90  then '61-90'
          when dtb.past_days >= 91 then '91+' 
          when dtb.past_days <5 then 'Current' else 'Dis_po' end
     case when dtb.l_grp_no= 7 then COMPANY_B else COMPANY_A end,
          case when lsc.SStatusC is not null 
                    and dtb.tbDATE> ls.eff_date Yearthen 
           lsc.SStatusC else 'XX'
      end
order by year(dtb.tbDATE), CONVERT(VARCHAR(12),dtb.tbDATE,110),
      case when dtb.l_grp_no= 7 then COMPANY_Belse COMPANY_A end
4

3 に答える 3

0

私が試みるのは、caseステートメントをUDFにカプセル化することです。これらは、通常のケースステートメントよりもUDFとしてより迅速に計算する必要があります。これにより、クエリの分析と保守も簡単になります。

于 2013-02-14T10:31:37.097 に答える
0

GROUP BY句から削除できる列が多いほど、優れています。処理する行数によっては、5-30、31-60などを保持するために「past_days_group」などの列を含む選択リストに基づいて一時テーブルまたはテーブル変数を作成する価値がある場合があります。 。CASE一時テーブルに挿入するときに現在groupby句にあるロジックを実行すると、「past_days_group」でグループ化された一時テーブルからクエリを選択できます。

于 2013-02-14T03:15:43.830 に答える
0

私はいくつかのことに気づきました。まず、最初にデータを調べれば、ケース構成を最適化できます。次に、true を返す可能性が最も高いケースが最初に検討されるように、ケースを並べ替えます。あなたはすでにそれを行っているかもしれませんが、それを伝えるのは難しいです.

次に、さらにフィルタリングを where 句から join 句に移動します。たとえば、次のようになります。

left outer join dw.dbo.AccSt_C lsc on lsc.Stat_C_ID= ls.status_code_no
WHERE dtb.l_grp_no in (7,4,8,15)and dtb.tbDATE > '2010-06-31' 
and dtb.P_bal+dtb.l_C_bal >0

次のように高速に実行される可能性があります。

left outer join dw.dbo.AccSt_C lsc on lsc.Stat_C_ID= ls.status_code_no
AND dtb.l_grp_no in (7,4,8,15)and dtb.tbDATE > '2010-06-31' 
and dtb.P_bal+dtb.l_C_bal >0

また、不要なフィールドは選択しないでください。ここのすべての列が本当に必要ですか?

left outer join (select stat_acct_l.* from sln.dbo.stat_acct_l

多分これらが役立つでしょう。

于 2013-02-14T00:10:39.883 に答える