1

我有一个查询需要提高效率。

我将其分解为几个部分以查看效率底线在哪里,我目前有一些嵌套选择语句,这些是性能问题吗?

以下是其中之一的示例:

SELECT AgreementID,
       DueDate,
       UpdatedAmountDue AS AmountDue,
       COALESCE((SELECT SUM(UpdatedAmountDue)
                 FROM RepaymentBreakdown AS B
                 WHERE CONVERT(datetime, CONVERT(varchar, DueDate, 103), 103) <= 
                       CONVERT(datetime, CONVERT(varchar, R.DueDate, 103), 103)
                 AND B.AgreementID = R.AgreementID),0) AS DueTD,
       RN=ROW_NUMBER() OVER (Partition BY R.AgreementID ORDER BY DueDate)
FROM RepaymentBreakdown AS R

有没有更干净高效的方式获取DueTD的数据?

基本上,对于还款计划结果的每一行,我想得到:

AgreementID,
DueDate,
AmountDue,
AmountDueToDate (DueTD)
RowNumber.

我查询的表结构如下:

AgreementID (int), 
DueDate (datetime),
AmountDue (decimal(9,2)),
UpdatedAmountDue (decimal(9,2))*

* UpdatedAmountDue 总是被引用,因为它是移动的图形,AmountDue 总是固定的,作为参考值。

4

2 回答 2

1

所以,我认为你可以通过删除转换来提高性能,如下所示:

select
    AgreementID,
    DueDate,
    UpdatedAmountDue as AmountDue,
    (
        select sum(B.UpdatedAmountDue)
        from RepaymentBreakdown as B
        where B.DueDate <= R.DueDate and B.AgreementID = R.AgreementID
    ) as UpdatedAmountDue 
from RepaymentBreakdown AS R

我知道在 SQL Server 2008 中计算运行总计的最快方法是使用递归 CTE,请参阅我的答案计算 SqlServer 中的运行总计。在您的情况下,查询将是这样的:

create table #t (....., primary key (AgreementID, ord))

insert into #t (AgreementID, DueDate, UpdatedAmountDue, ord)
select AgreementID, DueDate, UpdatedAmountDue, row_number() over (partition by AgreementID, DueDate order by DueDate asc)

;with 
CTE_RunningTotal
as
(
    select T.ord, T.AgreementID, T.DueDate, T.UpdatedAmountDue as T.AmountDue, T.UpdatedAmountDue
    from #t as T
    where T.ord = 1
    union all
    select T.ord, T.AgreementID, T.DueDate, T.UpdatedAmountDue as T.AmountDue, T.UpdatedAmountDue + C.UpdatedAmountDue as UpdatedAmountDue
    from CTE_RunningTotal as C
        inner join #t as T on T.ord = C.ord + 1 and T.AgreementID = C.AgreementID
)
select AgreementID, DueDate, AmountDue, UpdatedAmountDue
from CTE_RunningTotal as C
option (maxrecursion 0)
于 2013-07-03T09:06:59.773 回答
-1

您将日期时间转换为日期有几个问题。

首先,根据您的服务器语言设置,不能保证总是产生正确的结果。如果您需要对日期时间值进行字符串操作,请始终使用 CONVERT(,,126)。

但更重要的是,它可以防止索引的使用。而是使用CAST(DueDate AS DATE)as 优化器识别转换是索引安全的。

之后,您可能希望在 AgreementId、DueDate 和INCLUDEUpdatedAmountDue 上添加索引,或者更好地使其集群化。

假设 UpdatedAmountDue 不能为 NULL,你也可以去掉 COALESCE,因为总和总是包括当前行。

于 2013-07-02T13:45:42.697 回答