[英]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
可能第一个会做得更好一点,但两者都应该至少让你从每行的两次额外通过表中减少到一个。 如果您在表上有一个索引,包括同一索引中的TransType2
和TransDate
列,这些将特别有用,按该顺序。 如果这个索引在INCLUDE
部分也有BILLINGCLASSIFICATION
、 AMOUNTMST
和SETTLEAMOUNTMST
,那就更好了。 这将允许 JOIN/APPLY 完全在索引之外进行操作。 也可能只为TransType2
中的Customer
值做一个过滤索引。
当我在这里时,我还需要质疑float
是否足以处理货币价值。 您可能想要decimal
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.