如何优化T-SQL查询?

时间:2013-02-13 23:50:08

标签: sql sql-server optimization

我正在尝试优化以下查询以提高性能,尤其是连接。我非常感谢任何建议和帮助。非常感谢。 我想使用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

3 个答案:

答案 0 :(得分: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

也许这会有所帮助。

答案 1 :(得分:0)

您可以从GROUP BY子句删除的列越多越好。根据您正在处理的行数,根据您的选择列表创建临时表或表变量可能是值得的,该列表包含名为“past_days_group”的列,以容纳5-30,31-60等。 。插入临时表时,执行当前在group by子句中的CASE逻辑,然后可以通过“past_days_group”从临时表分组中选择查询。

答案 2 :(得分:0)

我会尝试将您的case语句封装到UDF中。这些应该像UDF一样比常规案例陈述更快地计算。这也可以使您的查询更容易分析和维护。