如何提高查询效率?

时间:2017-03-01 17:35:03

标签: sql sql-server-2012

我有下面的查询,我已经删除了大部分内容,因为有大约20个条件,它只会太长而且太复杂而无法放入。我的查询有效,我得到的数据正如我想要的那样是我今年的数据和我之前的数据。这是通过前一年的一些子查询实现的,其中我从当前财政年度减去1。现在,当我的查询变得更复杂并且我添加了15个这样的子查询时,由于我拥有的数据量,它有时可能需要12个多小时才能运行。我是否有更有效的方式来编写此查询?

修改

不确定为什么在一个完全有效的问题上有这么多的投票。

    SELECT
        period,
        finyear,
        fin_week,
        region,
        store,
        salesperson,

        SUM(Fin_Revenue) as total_rev_ty,
        SUM(CASE WHEN status_rev IN ('refund') THEN Fin_Revenue ELSE 0 END) as refund_rev_ty,
        SUM(CASE WHEN status_rev IN ('credit') Fin_Revenue ELSE 0 END) as credit_rev_ty,

          (
            SELECT SUM(Fin_Revenue)
            FROM [MYDB] r2
            where r1.store = r2.store
            AND r1.fin_week = r2.fin_week
            AND r1.Salesperson = r2.Salesperson
            AND r1.fin_yr = dateadd(yy,1,r2.fin_yr)
          ) as total_rev_ly,


          (
            SELECT SUM(CASE WHEN status_rev IN ('refund') THEN Fin_Revenue ELSE 0 END)
            FROM [MYDB] r2
            where r1.store = r2.store
            AND r1.fin_week = r2.fin_week
            AND r1.Salesperson = r2.Salesperson
            AND r1.fin_yr = dateadd(yy,1,r2.fin_yr)
          ) as refund_rev_ly,

        (SELECT
        SUM(CASE WHEN status_rev IN ('credit') Fin_Revenue ELSE 0 END)
            FROM [MYDB] r2
            where r1.store = r2.store
            AND r1.fin_week = r2.fin_week
            AND r1.Salesperson = r2.Salesperson
            AND r1.fin_yr = dateadd(yy,1,r2.fin_yr)
          ) as refund_rev_ly

FROM [MYDB] r1

        WHERE
        fin_yr IN ('2016')

1 个答案:

答案 0 :(得分:2)

case语句使您的查询以顺序模式运行,这使得它非常慢。 您可以将子查询更改为:

  (
    SELECT SUM(Fin_Revenue) as refund
    FROM [MYDB] r2
    where r1.store = r2.store
    AND r1.fin_week = r2.fin_week
    AND r1.Salesperson = r2.Salesperson
    AND r1.fin_yr = dateadd(yy,1,r2.fin_yr)
    AND status_rev ='refund'
  ) as refund_rev_ly,

(SELECT SUM(Fin_Revenue) as credit
    FROM [MYDB] r2
    where r1.store = r2.store
    AND r1.fin_week = r2.fin_week
    AND r1.Salesperson = r2.Salesperson
    AND r1.fin_yr = dateadd(yy,1,r2.fin_yr)
    AND status_rev  = 'credit'
  ) as refund_rev_ly

如果您有索引 status_rev 列,则子查询的运行速度会快得多。

还可以进行其他改进,但这是我可以建议的侵入性最小的。