SQL CTE可以提高性能

时间:2014-02-25 19:56:08

标签: sql common-table-expression

您好我对CTE不太熟悉。我使用select case语句创建了一个子查询,应用程序架构师指出,如果使用CTE可以提高性能,我尝试了几次尝试但没有成功,这是我修改的查询:

更新** 我正在使用本地数据库。我将添加完整的工作查询,虽然它是一个大的,我只被通知提高LEFT OUTER JOIN的性能我添加了select case语句。

    IF EXISTS (SELECT * FROM sysobjects WHERE type = 'V' AND name = 'VW_TRPRINT_TITLERECORD1')
    BEGIN
        DROP  View VW_TRPRINT_TITLERECORD1
    END
GO

Create VIEW VW_TRPRINT_TITLERECORD1
 as 
SELECT               
distinct(T.TTL_NUMBER), T.OWNERSHIP_DOC_ID      
, OD.TXN_ID    
, TX.TXN_DATE    
, OWNSHIP.CUS_ID   

, PTA.CUS_FULLNAME_PART1 AS PRIMARY_OWNER_NAME  
, PTA.CUS_FULLNAME_PART2 AS SECOND_OWNER_NAME  
, PTA.CUS_ADDR_ID   

, CUST_ADDR.ADDRESS_LINE_1 AS PRIMARY_OWNER_STREET_LINE_1                        --PRIMARY OWNER NAME AND ADDRESS DETAILS    
, CUST_ADDR.CITY  AS PRIMARY_OWNER_CITY    
, CUST_ADDR.STATE AS PRIMARY_OWNER_STATE    
, CUST_ADDR.ZIP_CODE AS PRIMARY_OWNER_ZIP_CODE    
, CUST_ADDR.ZIP_PLUS AS PRIMARY_OWNER_ZIP_PLUS    
, CUST_ADDR.POSTNET_BARCODE  AS PRIMARY_OWNER_COUNTY    


, PTA.FIRST_LIEN_NAME  AS FIRST_SECURED_NAME  
, PTA.FIRST_LOAN_DATE AS  LOAN_DATE  
, PTA.FIRST_LIEN_ADDRESS_ID   


, FIRST_LIEN_ADDR.ADDRESS_LINE_1 AS FIRST_SECURED_STREET_LINE_1                   --FIRST SECURED PARTY ADDRESS DETAILS     
, FIRST_LIEN_ADDR.CITY  AS FIRST_SECURED_CITY    
, FIRST_LIEN_ADDR.STATE AS FIRST_SECURED_STATE    
, FIRST_LIEN_ADDR.ZIP_CODE AS FIRST_SECURED_ZIP_CODE    
, FIRST_LIEN_ADDR.ZIP_PLUS AS FIRST_SECURED_ZIP_PLUS    
, FIRST_LIEN_ADDR.POSTNET_BARCODE  AS FIRST_LIEN_COUNTY   

, PTA.SECOND_LIEN_NAME AS SECOND_SECURED_PARTY_NAME  
, PTA.SECOND_LOAN_DATE   
, PTA.SECOND_LIEN_ADDRESS_ID   
, PTA.MAIL_TITLE_TO_SECURED_PARTY   

, SECOND_LIEN_ADDR.ADDRESS_LINE_1 AS SECOND_SECURED_STREET_1                     --SECOND SECURED PARTY ADDRESS DETAILS
, SECOND_LIEN_ADDR.CITY  AS SECOND_SECURED_CITY   
, SECOND_LIEN_ADDR.STATE AS SECOND_SECURED_STATE    
, SECOND_LIEN_ADDR.ZIP_CODE AS SECOND_SECURED_ZIPCODE    
, SECOND_LIEN_ADDR.ZIP_PLUS AS SECOND_SECURED_ZIP_PLUS    
, SECOND_LIEN_ADDR.POSTNET_BARCODE  AS SECOND_LIEN_COUNTY   

, TMP.ADDRESSEE  AS SPECIAL_MAIL_NAME                                             --SPECIAL MAILING NAME AND ADDRESS DETAILS       
, TMP.ADDRESS_LINE_1 AS SPECIAL_MAILING_LINE_1    
, TMP.CITY AS SPECIAL_MAILING_CITY    
, TMP.STATE AS SPECIAL_MAILING_STATE    
, TMP.ZIP_CODE AS SPELCIAL_MAILING_ZIP_CODE    
, TMP.ZIP_PLUS AS SPECIAL_MAILING_ZIP_PLUS    
, TMP.POSTNET_BARCODE AS SPELCIAL_MAILING_COUNTY     

, MAIL_TO_NAME   
, MAIL_TO_ADDR.ADDRESS_LINE_1 AS MAIL_TO_STREET_LINE_1  
, MAIL_TO_ADDR.CITY AS MAIL_To_CITY
, CASE WHEN MAIL_TO_ADDR.STATE = '' THEN 
    NULL ELSE
    MAIL_TO_ADDR.STATE END AS
    MAIL_TO_STATE    
, CASE WHEN MAIL_TO_ADDR.ZIP_CODE = '' THEN
    NULL ELSE
    MAIL_TO_ADDR.ZIP_CODE END AS
    MAIL_TO_ZIP_CODE    
, MAIL_TO_ADDR.ZIP_PLUS AS MAIL_TO_ZIP_PLUS    
, MAIL_TO_ADDR.POSTNET_BARCODE  AS MAIL_TO_ZIP_COUNTY   


,'MAILING_CODE' = CASE               
    --WHEN TMP.ADDRESS_ID IS NOT NULL THEN 'M'    
    WHEN PTA.MAIL_TITLE_TO_SECURED_PARTY = 1  THEN 'S'              
    WHEN TMP.ADDRESS_ID IS NULL AND OWNSHIP.IS_MAIL_OWNER = 1 AND PTA.MAIL_TITLE_TO_SECURED_PARTY = 0 AND (PTA.CUS_ADDR_ID = PTA.MAIL_TO_ADDRESS_ID OR MAIL_TO_ADDR.ADDRESS_LINE_1 = CUST_ADDR.ADDRESS_LINE_1) THEN '' 
    ELSE 'M'
 END         

 FROM VW_NONVOIDED_TITLES T               

 INNER JOIN PRESERVE_TITLE_ATTRIBUTES PTA ON PTA.TITLES_ID  = T.ID  
 LEFT OUTER JOIN  ADDRESSES CUST_ADDR ON CUST_ADDR.ID = PTA.CUS_ADDR_ID     
 LEFT OUTER JOIN ADDRESSES FIRST_LIEN_ADDR ON FIRST_LIEN_ADDR.ID = PTA.FIRST_LIEN_ADDRESS_ID  
 LEFT OUTER JOIN ADDRESSES SECOND_LIEN_ADDR ON SECOND_LIEN_ADDR.ID = PTA.SECOND_LIEN_ADDRESS_ID   
 LEFT OUTER JOIN ADDRESSES MAIL_TO_ADDR ON MAIL_TO_ADDR.ID = 
    (SELECT                 
                CASE WHEN SMA.DOC_ID = 6 THEN 
                    PTA.CUS_ADDR_ID  
                ELSE
                PTA.MAIL_TO_ADDRESS_ID  
                END
            FROM
            PRESERVE_TITLE_ATTRIBUTES PA
            INNER JOIN SPECIAL_MAILING_ADDRESS SMA ON SMA.ADDRESS_ID = PTA.MAIL_TO_ADDRESS_ID AND PA.ID  =PTA.ID )   

  /*Title Contains a Second Owner*/      
 INNER JOIN VW_NONVOIDED_OWNERSHIP_DOCUMENT OD ON OD.ID = T.OWNERSHIP_DOC_ID  --AND OD.END_DATE IS NULL   
 INNER JOIN VW_NONVOIDED_OWNERSHIPS OWNSHIP ON OWNSHIP.OWNERSHIP_DOCUMENT_ID = OD.ID AND OWNSHIP.IS_MAIL_OWNER = 1 --AND OWNSHIP.END_DATE IS NULL   
 INNER JOIN VW_NONVOIDED_VEHICLES V ON V.ID = OD.VEH_ID AND V.END_DATE IS NULL    
 INNER JOIN TXN TX ON TX.ID = OD.TXN_ID    

我修改了最后一个连接选择案例语句,可以通过CTE进行改进。 任何关于如何实现这一点的建议或指针将不胜感激。

1 个答案:

答案 0 :(得分:1)

这是子查询和cte的语法。

<强>子查询:

SELECT *
FROM (SELECT *
      FROM Table1
      WHERE Stuff = 'Wee'
      )sub

<强> CTE:

WITH cte AS (SELECT *
             FROM Table1
             WHERE Stuff = 'Wee')
SELECT *
FROM cte

同一查询的等效cte和子查询版本通常会生成相同的执行计划(无性能增益)。当子查询必须被多次引用时,Cte可以更清晰,并且它们允许递归。