如何在MS SQL中提高以下查询的性能

时间:2015-07-28 18:03:37

标签: sql performance sql-server-2008 query-optimization database-performance

以下查询现在速度非常慢,需要建议以提高性能。

SQL QUERY:

USE AGENCYDATA

SELECT      reporting_period
            ,SUM(current_upb) as upb
            ,SUM(smm_prepay) as smm_prepay
            ,SUM(smm_default) as smm_default
            ,case when sum(current_upb)>0 then (1-power(1-SUM(smm_prepay)/SUM(current_upb+smm_prepay+smm_default),12))*100 else 0 end as CPR
            ,case when sum(current_upb)>0 then (1-power(1-SUM(smm_default)/SUM(current_upb+smm_prepay+smm_default),12))*100 else 0 end as CDR
            ,SUM(prior_upb-current_upb) as paydown

FROM (
            SELECT      p.loan_id
                        ,reporting_period
                        ,current_upb
                        ,p.prior_upb                                                                                                                                                                      
                        ,p.zero_balance_code
                        ,case when zero_balance_code='01' then p.prior_upb else 0 end as smm_prepay
                        ,case when zero_balance_code in ('03','09') and repurchase_flag='N' then p.prior_upb else 0 end as smm_default

            FROM Performance p
            join  (
                              SELECT p.loan_id
                              FROM Performance p                                                                        
                              LEFT JOIN Acquisition a on    p.gse_buyer=a.gse_buyer 
                                                                        and p.loan_id=a.loan_id
                              LEFT JOIN (
                                                      SELECT loan_id,reporting_period,dq_status
                                                      FROM Performance
                                             ) prev   on prev.loan_id=p.loan_id 
                                                                        and prev.reporting_period=DATEADD(month,-1,p.reporting_period)
                              WHERE p.dq_status = '0' 
                                          and prev.dq_status not in ('0','1','2') 
                                          and p.gse_buyer='FHR'
                                          and a.acquisition_quarter in ('2009Q1','2009Q2','2009Q3','2009Q4')
                  ) d ON d.loan_id=p.loan_id
) b
GROUP BY 
            reporting_period
ORDER BY 
            reporting_period

绩效表的架构:

    CREATE TABLE [dbo].[Performance](
    [performanceId] [int] IDENTITY(1,1) NOT NULL,
    [gse_buyer] [varchar](4) NULL,
    [loan_id] [varchar](32) NULL,
    [reporting_period] [date] NULL,
    [prior_upb] [numeric](12, 2) NULL,
    [current_upb] [numeric](12, 2) NULL,
    [dq_status] [varchar](5) NULL,
    [loan_age] [numeric](10, 0) NULL,
    [remaining_months_to_maturity] [numeric](3, 0) NULL,
    [current_int_rate] [numeric](14, 10) NULL,
    [zero_balance_code] [varchar](2) NULL,
    [zero_balance_effective_date] [date] NULL,
    [modification_flag] [varchar](1) NULL,
    [servicer_name_fn] [varchar](80) NULL,
    [adjusted_remaining_months_to_maturity] [numeric](3, 0) NULL,
    [maturity_date_fn] [date] NULL,
    [repurchase_date] [date] NULL,
    [repurchase_flag] [varchar](2) NULL,
    [metropolitan_statistical_area_fn] [varchar](5) NULL,
    [current_deferred_upb] [numeric](12, 2) NULL,
    [paid_through_date] [date] NULL,
    [mi_recovery] [numeric](12, 2) NULL,
    [net_sales_proceeds] [varchar](30) NULL,
    [non_mi_recovery] [numeric](12, 2) NULL,
    [expense] [numeric](12, 2) NULL
) ON [PRIMARY]

收购表的架构:

     CREATE TABLE [dbo].[Acquisition](
    [acquisitionId] [int] IDENTITY(1,1) NOT NULL,
    [gse_buyer] [varchar](4) NULL,
    [loan_id] [varchar](20) NULL,
    [channel] [varchar](1) NULL,
    [seller_name] [varchar](80) NULL,
    [servicer_name_fh] [varchar](80) NULL,
    [acquisition_quarter] [varchar](6) NULL,
    [orig_int_rate] [numeric](14, 10) NULL,
    [orig_upb] [numeric](11, 2) NULL,
    [orig_loan_term] [numeric](3, 0) NULL,
    [orig_date] [date] NULL,
    [first_payment_date] [date] NULL,
    [maturity_date] [date] NULL,
    [orig_ltv] [numeric](14, 10) NULL,
    [orig_cltv] [numeric](14, 10) NULL,
    [number_of_borrowers] [numeric](3, 0) NULL,
    [dti_ratio] [numeric](14, 10) NULL,
    [borrower_credit_score] [numeric](3, 0) NULL,
    [first_time_home_buyer_indicator] [varchar](1) NULL,
    [loan_purpose] [varchar](1) NULL,
    [property_type] [varchar](2) NULL,
    [number_of_units] [varchar](10) NULL,
    [occupancy_status] [varchar](1) NULL,
    [zipcode] [varchar](10) NULL,
    [metropolitan_statistical_area] [varchar](5) NULL,
    [property_state] [varchar](20) NULL,
    [mortgage_insurance_percentage] [numeric](14, 10) NULL,
    [product_type] [varchar](20) NULL,
    [prepay_panalty_flag] [varchar](1) NULL,
    [co_borrower_credit_score] [numeric](3, 0) NULL
) ON [PRIMARY]

有人可以帮助我提高此查询的效果吗?该查询已持续运行1小时,但未获得任何结果。

1 个答案:

答案 0 :(得分:1)

我认为你的主要问题是你在没有连接的情况下再次使用同一个表。您可以尝试以下方式:

SELECT      reporting_period
            ,SUM(current_upb) as upb
            ,SUM(smm_prepay) as smm_prepay
            ,SUM(smm_default) as smm_default
            ,case when sum(current_upb)>0 then (1-power(1-SUM(smm_prepay)/SUM(current_upb+smm_prepay+smm_default),12))*100 else 0 end as CPR
            ,case when sum(current_upb)>0 then (1-power(1-SUM(smm_default)/SUM(current_upb+smm_prepay+smm_default),12))*100 else 0 end as CDR
            ,SUM(prior_upb-current_upb) as paydown

FROM (
            SELECT      p.loan_id
                        ,p.reporting_period
                        ,p.current_upb
                        ,p.prior_upb                                                                                                                                                                      
                        ,p.zero_balance_code
                        ,case when p.zero_balance_code='01' then p.prior_upb else 0 end as smm_prepay
                        ,case when p.zero_balance_code in ('03','09') and p.repurchase_flag='N' then p.prior_upb else 0 end as smm_default

            FROM Performance p
            join  Performance prev
                on prev.loan_id=p.loan_id 
                and prev.reporting_period=DATEADD(month,-1,p.reporting_period)
            LEFT JOIN Acquisition a 
                on p.gse_buyer=a.gse_buyer 
                    and p.loan_id=a.loan_id


                              WHERE p.dq_status = '0' 
                                          and prev.dq_status not in ('0','1','2') 
                                          and p.gse_buyer='FHR'
                                          and a.acquisition_quarter in ('2009Q1','2009Q2','2009Q3','2009Q4')
) b
GROUP BY 
            reporting_period
ORDER BY 
            reporting_period