简体   繁体   English

如何优化T-SQL查询?

[英]How to optimize T-SQL Query?

I am trying to optimize the following query to increase the performance particularly the joins. 我正在尝试优化以下查询以提高性能,尤其是联接。 I would greatly appreciate any suggestions and help. 我将不胜感激任何建议和帮助。 Thanks a lot. 非常感谢。 I am thinking to use CTE instead of subqueries 我正在考虑使用CTE代替子查询

Query: 查询:

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

I noticed a couple of things. 我注意到了几件事。 First, you can optimize your case constructs if you first take a look at your data. 首先,如果您先查看数据,则可以优化案例结构。 Then order your cases so that the ones that are most likely to return true are looked at first. 然后对您的案例进行排序,以便首先查看最有可能返回true的案例。 You may have already done that, it's hard to tell. 您可能已经做到了,这很难说。

Next, move more filtering from the where clause to the join clause. 接下来,将更多过滤从where子句移到join子句。 For example, this: 例如,这:

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

might run faster like this: 可能会这样运行得更快:

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

Also, don't select field you don't need. 另外,不要选择不需要的字段。 Do you really need every column here? 您真的需要这里的每一列吗?

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

Maybe these will help. 也许这些会有所帮助。

The more columns you can remove from the GROUP BY clause, the better. 您可以从GROUP BY子句中删除的列越多越好。 Depending on the number of rows you are dealing with, it may be worth it to make a temp table or table variable based on your select list that includes a column called something like "past_days_group" to hold 5-30, 31-60 etc.. Do the CASE logic that is currently in your group by clause when inserting to the temp table, then you can select your query out of the temp table grouping by "past_days_group". 根据您要处理的行数,可能有必要根据您的选择列表创建一个临时表或表变量,其中包括一个名为“ past_days_group”的列,以容纳5-30、31-60等。 。在插入临时表时,执行group by子句中当前存在的CASE逻辑,然后可以从“ past_days_group”的临时表分组中选择查询。

What I would try is to encapsulate your case statements into UDFs. 我将尝试将您的case语句封装到UDF中。 These should be calculated quicker as UDF than like regular case statements. 作为UDF,这些规则应该比常规的case语句更快地计算出来。 This would also make your query easier to analyze and maintain. 这也将使您的查询更易于分析和维护。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM