查询速度优化

MrT*_*MrT 2 performance sql-server optimization query-performance

我有几个表,我试图将它们与以下查询结合起来。我正在使用以下表格:

  • LoanOrigination:这包含贷款特征,例如资产价值、贷款期限等。每笔贷款有一个独特的观察。该表在LOAN_IDSUB_SAMPLE和上建立索引COLLATERAL_TYPE
  • LoanPerformance:这包含了所有贷款的表现LoanOrigination。每一行是一个独特的MONTHLY_REPORTING_PERIODLOAN_ID组合,并且该表已被索引两个。
  • CollateralData:这包含基于COLLATERAL_TYPE. 这样做的目的是估计贷款对抵押品的当前价值。

下面查询的目的是组合这些表,以便每一行都包含贷款特征以及当月和下个月的拖欠状态。但是,查询速度非常慢。有什么办法可以加快速度吗?

with

COLLATERAL_VALUES as (
    select
        COLLATERAL_TYPE,
        dateadd( day, 1-day(AsOfDate), AsOfDate) as ASOFDATE,
        Value as INDEX
    from LoanData.CollateralData
),

SAMPLE_LOANS as (
    select
        a.*,
        b.INDEX as INDEX_T0
    from LoanData.LoanOrigination a
    join COLLATERAL_VALUES b on b.ASOFDATE = a.ORIG_DATE and b.COLLATERAL_TYPE = a.COLLATERAL_TYPE
    where SUB_SAMPLE = 0
),

LOAN_STATE as (
    select
        a.LOAN_ID,
        MONTHLY_REPORTING_PERIOD AS CUR_DATE,
        CURRENT_ACTUAL_UPB as CUR_UPB,
        LOAN_AGE,
        cast(CURRENT_LOAN_DELINQUENCY as smallint) AS CUR_DLQ_STATUS
    from LoanData.LoanPerformance a
    where
        CURRENT_LOAN_DELINQUENCY <> 'XX' and
        exists ( select LOAN_ID from SAMPLE_LOANS )
),

LOAN_TRANSITION as (
    select
        c.*,
        a.CUR_DATE,
        a.CUR_DLQ_STATUS,
        a.CUR_UPB,
        a.LOAN_AGE,
        b.NEXT_DLQ_STATUS
    from LOAN_STATE a
    join (
        -- adding next state transition
        select
            LOAN_ID,
            DATEADD( month, -1, CUR_DATE ) as PRIOR_DATE,
            CUR_DLQ_STATUS as NEXT_DLQ_STATUS
        from LOAN_STATE
    ) b on a.LOAN_ID = b.LOAN_ID and a.CUR_DATE = b.PRIOR_DATE
    join SAMPLE_LOANS c on a.LOAN_ID = c.LOAN_ID
)

select
    a.*,
    CUR_UPB / ( ASSET_VALUE * ( b.INDEX / a.INDEX_T0 )) AS LTV
from LOAN_TRANSITION a
join COLLATERAL_VALUES b on a.CUR_DATE = b.ASOFDATE and a.COLLATERAL_TYPE = b.COLLATERAL_TYPE
Run Code Online (Sandbox Code Playgroud)

Rob*_*ley 10

每当您加入 using 时都会遇到问题ASOFDATE,例如:

on a.CUR_DATE = b.ASOFDATE
Run Code Online (Sandbox Code Playgroud)

,因为ASOFDATE定义为dateadd( day, 1-day(AsOfDate), AsOfDate)。对我来说,这似乎意味着“本月的第一天”,希望不涉及时间部分。

所以,我会在第一个 CTE 中添加一个新列,称为可能AsOfDateOrig

COLLATERAL_VALUES as (
select
    COLLATERAL_TYPE,
    dateadd( day, 1-day(AsOfDate), AsOfDate) as ASOFDATE,
    Value as INDEX
    ,AsOfDate as AsOfDateOrig
from LoanData.CollateralData
),
Run Code Online (Sandbox Code Playgroud)

然后也将其包含在您的 join 子句中。

on a.CUR_DATE = b.ASOFDATE
and b.AsOfDateOrig >= a.CUR_DATE and b.AsOfDateOrig < dateadd(month,1,a.CUR_DATE)
Run Code Online (Sandbox Code Playgroud)

两者兼而有之似乎有些多余,但它允许 QO使用任一方法作为主要的 Seek Predicate。

现在对您使用它加入的其他任何地方执行相同的操作。

我也会考虑做同样的PRIOR_DATE事情,基本上避免涉及表达式的连接,除非你也有它的逆。

最后,看看你的索引策略。

LoanData.CollateralData (COLLATERAL_TYPE, AsOfDate) INCLUDE (Value)例如,您将需要一个索引,以及其他表上的类似索引。