繁体   English   中英

如何提高相关子查询的速度

[英]How to improve speed of a correlated sub-query

我有一个相关的子查询,我需要向其中添加更多子查询。 到目前为止,我知道这条路线会导致查询缓慢。 我还能如何解决这个问题?

select

  c.TRANSDATE as Transdate,

  lag(sum(convert(float,c.AMOUNTMST-c.SETTLEAMOUNTMST)),1) over(order by c.TRANSDATE) as "Beginning 
Balance",

    (( select top 1 sum(convert(float,c2.AMOUNTMST-c2.SETTLEAMOUNTMST))
      from [AX2cTestStage].[dbo].[CUSTTRANS_V] c2
      where c2.BILLINGCLASSIFICATION = 'ACT Payment' and c2.TransType2 = 'Customer' and c2.TRANSDATE 
= c.TRANSDATE
      group by c2.TRANSDATE
    ))as "FTI-ACT Payment",

    (( select top 1 sum(convert(float,c3.AMOUNTMST-c3.SETTLEAMOUNTMST))
      from [AX2cTestStage].[dbo].[CUSTTRANS_V] c3
      where c3.BILLINGCLASSIFICATION = 'Bulk' and c3.TransType2 = 'Customer' and c3.TRANSDATE = 
c.TRANSDATE
      group by c3.TRANSDATE
    ))as "FTI-Bulk",
  sum(convert(float,c.AMOUNTMST-c.SETTLEAMOUNTMST)) as "Actual Ending Balance"
from [AX2cTestStage].[dbo].[CUSTTRANS_V] c
group by c.TRANSDATE
order by c.TRANSDATE

结果:

Transdate       Beginning Balance       FTI-ACT Payment     FTI-Bulk        Actual Ending Balance
2019-04-12              NULL                  NULL            NULL                -22591.47
2019-04-15             -22591.47              599.69          NULL                 -394.95
2019-04-25             -394.95                NULL            2539.57              -1776
2019-04-26             -1776                  NULL            NULL                 -11973.84

您的查询可以从复合索引中受益:

create index ix1 on [AX2cTestStage].[dbo].[CUSTTRANS_V] 
  (BILLINGCLASSIFICATION, TransType2, TRANSDATE);

我看到两个选项:

一、JOIN+条件聚合:

SELECT
    c.TRANSDATE as Transdate,
    lag(sum(convert(float,c.AMOUNTMST-c.SETTLEAMOUNTMST)),1) over(order by c.TRANSDATE) as [Beginning Balance],
    sum(case when c2.BILLINGCLASSIFICATION = 'ACT Payment' THEN convert(float,c2.AMOUNTMST-c2.SETTLEAMOUNTMST) ELSE 0 END) AS [FTI-ACT Payment],
    sum(case when c2.BILLINGCLASSIFICATION = 'Bulk' THEN convert(float,c2.AMOUNTMST-c2.SETTLEAMOUNTMST) ELSE 0 END) As [FTI-Bulk],
    sum(convert(float,c.AMOUNTMST-c.SETTLEAMOUNTMST)) as [Actual Ending Balance]
FROM[AX2cTestStage].[dbo].[CUSTTRANS_V] c
LEFT JOIN [AX2cTestStage].[dbo].[CUSTTRANS_V] c2 ON c2.TRANSDATE = c.TRANSDATE AND c2.TransType2 = 'Customer'
GROUP BY c.TRANSDATE
ORDER BY c.TRANSDATE

或者横向连接+条件聚合:

SELECT
    c.TRANSDATE as Transdate,
    lag(sum(convert(float,c.AMOUNTMST-c.SETTLEAMOUNTMST)),1) over(order by c.TRANSDATE) as [Beginning Balance],
    c2.[FTI-ACT Payment], c2.[FTI-Bulk],
    sum(convert(float,c.AMOUNTMST-c.SETTLEAMOUNTMST)) as [Actual Ending Balance]
FROM[AX2cTestStage].[dbo].[CUSTTRANS_V] c
OUTER APPLY (
    SELECT 
        sum(case when c2.BILLINGCLASSIFICATION = 'ACT Payment' THEN convert(float,c2.AMOUNTMST-c2.SETTLEAMOUNTMST) ELSE 0 END) AS [FTI-ACT Payment],
        sum(case when c2.BILLINGCLASSIFICATION = 'Bulk' THEN convert(float,c3.AMOUNTMST-c3.SETTLEAMOUNTMST) ELSE 0 END) As [FTI-Bulk]
    FROM [AX2cTestStage].[dbo].[CUSTTRANS_V] c2
    WHERE c2.TRANSDATE = c.TRANSDATE AND c2.TransType2 = 'Customer'
    GROUP BY c2.TRANSDATE
) c2
GROUP BY c.TRANSDATE
ORDER BY c.TRANSDATE

可能第一个会做得更好一点,但两者都应该至少让你从每行的两次额外通过表中减少到一个。 如果您在表上有一个索引,包括同一索引中的TransType2TransDate列,这些将特别有用,按该顺序。 如果这个索引在INCLUDE部分也有BILLINGCLASSIFICATIONAMOUNTMSTSETTLEAMOUNTMST ,那就更好了。 这将允许 JOIN/APPLY 完全在索引之外进行操作。 也可能只为TransType2中的Customer值做一个过滤索引

当我在这里时,我还需要质疑float是否足以处理货币价值。 您可能想要decimal

暂无
暂无

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

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