2016-01-05 56 views
2

我有一個查詢像下面,在SQL Server 2008表現不佳的SQL查詢

SELECT 
    ipm.HEORG_REFNO,  
    ipm.HOTYP_REFNO,  
    ipm.CASLT_REFNO,  
    ipm.HOLVL_REFNO,  
    IPM.MAIN_IDENT, 
    ... 
FROM 
    dbo.HEALTH_ORGANISATIONS ipm (NOLOCK)    
LEFT JOIN 
    (SELECT 
     s.heorg_refno, min(s.start_dttm) as start_dttm_SPONT, max(isnull(convert(datetime,s.end_dttm,120),convert(datetime,'9999-01-01', 120))) as end_dttm_SPONT  
    FROM 
     dbo.service_points s (NOLOCK)  
    INNER JOIN 
     dbo.reference_values rfval (NOLOCK) ON s.SPTYP_REFNO = rfval.RFVAL_REFNO  
              AND RFVAL.MAIN_CODE != 'PDT'   
    GROUP BY 
     s.heorg_refno) SPONT ON ipm.HEORG_REFNO = SPONT.HEORG_REFNO  

-- Bring only Health Organisation records and also certain records,whose HOTYP_REFNO does not exist in REF_VALS 
WHERE 
    NOT EXISTS ((SELECT 'x' 
       FROM REFERENCE_VALUES RVAL (NOLOCK) 
       WHERE RVAL.RFVAL_REFNO = ipm.HOTYP_REFNO 
        AND main_code IN ('011','012','015','016', '017','019','2','AANDE','AEB','AEC','CLINIC','DAYCC','DEPRT','GPSIT','HC','HOSPL','HOST','LOCTN','LOSYN','MIU','MISC','MRL', 'SITE','THEAT','WARD','PDT','NURHM','DAYCR') 
    or ipm.HEORG_REFNO IN(select distinct HEORG_REFNO from SERVICE_POINT_SESSIONS (NOLOCK) where OWNER_HEORG_REFNO = 2001934 and HEORG_REFNO != 2001934) 
    or ipm.HEORG_REFNO IN (select REFNO from LOR_IPM_SYNTH_STG_DEV.. STAGING_Activity_LOCATION_DCS (NOLOCK) where Sources='HEORG_REFNO' and REFNO != 2001934) 
    ) 
) 

它需要地獄了大量的時間來執行查詢執行。

當我發表意見低於2行,它的運行速度更快:

or ipm.HEORG_REFNO IN(select distinct HEORG_REFNO from SERVICE_POINT_SESSIONS (NOLOCK) where OWNER_HEORG_REFNO = 2001934 and HEORG_REFNO != 2001934) 
    or ipm.HEORG_REFNO IN (select REFNO from LOR_IPM_SYNTH_STG_DEV.. STAGING_Activity_LOCATION_DCS (NOLOCK) where Sources='HEORG_REFNO' and REFNO != 2001934) 

感謝您對調節查詢提供任何指導

+0

做選擇部分不存在要永遠運行自己? – pancho018

+1

踢壞的壞習慣:[把'NOLOCK'無處不在](http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/)。可能的影響:髒讀,缺少行,讀取兩次行,讀取同一行的多個版本,索引損壞,讀取錯誤... –

+0

沒有..它運行得很快.. – NetTechie

回答

1

嘗試那些IN子查詢轉換爲JOIN查詢像下面,並確保您在連接條件中涉及的所有列上創建了適當的索引,並在過濾器條件中創建了索引

LEFT JOIN SERVICE_POINT_SESSIONS sps ON ipm.HEORG_REFNO = sps.HEORG_REFNO 
AND sps.OWNER_HEORG_REFNO = 2001934 
AND sps.HEORG_REFNO != 2001934 

我會修改您的查詢,如下所示。儘管我現在對你的大名單不能做任何事情,但是你應該把這個名單放在一個表格變量中,然後考慮做一個JOIN

SELECT 
    ipm.HEORG_REFNO,  
    ipm.HOTYP_REFNO,  
    ipm.CASLT_REFNO,  
    ipm.HOLVL_REFNO,  
    IPM.MAIN_IDENT, 
    ... 
FROM 
    dbo.HEALTH_ORGANISATIONS ipm    
LEFT JOIN 
    (SELECT 
     s.heorg_refno, min(s.start_dttm) as start_dttm_SPONT, 
     max(isnull(convert(datetime,s.end_dttm,120),convert(datetime,'9999-01-01', 120))) as end_dttm_SPONT  
    FROM 
     dbo.service_points s  
    INNER JOIN dbo.reference_values rfval 
    ON s.SPTYP_REFNO = rfval.RFVAL_REFNO 
    AND RFVAL.MAIN_CODE != 'PDT'   
    GROUP BY 
     s.heorg_refno) SPONT ON ipm.HEORG_REFNO = SPONT.HEORG_REFNO 

LEFT JOIN SERVICE_POINT_SESSIONS sps 
ON ipm.HEORG_REFNO = sps.HEORG_REFNO 
AND sps.OWNER_HEORG_REFNO = 2001934 
AND sps.HEORG_REFNO != 2001934 

LEFT JOIN LOR_IPM_SYNTH_STG_DEV .. STAGING_Activity_LOCATION_DCS sald 
ON ipm.HEORG_REFNO = sald.HEORG_REFNO 
AND sald.Sources='HEORG_REFNO' 
AND sald.REFNO != 2001934 

WHERE NOT EXISTS (SELECT 1 
       FROM REFERENCE_VALUES RVAL 
       WHERE RVAL.RFVAL_REFNO = ipm.HOTYP_REFNO 
       AND RVAL.main_code IN ('011','012','015','016', '017','019','2','AANDE','AEB','AEC','CLINIC','DAYCC','DEPRT','GPSIT','HC','HOSPL','HOST','LOCTN','LOSYN','MIU','MISC','MRL', 'SITE','THEAT','WARD','PDT','NURHM','DAYCR')); 
+0

對不起..使它成爲左連接doesn' t幫助..我們也沒有DB的權利..它的'只讀'的所有實用目的... – NetTechie

+0

對不起..我不基本上檢查記錄從IPM不存在服務點會議表..我甚至添加了'WHERE SPSSN.HEORG_REFNO IS NULL'子句..但它仍然沒有給出所需的輸出.. – NetTechie

2

我的第一個想法是,你的查詢是大量複雜的 - 我會尋找方法來簡化它...

在條款並不總是表現良好 - 我會被誘惑到這個吸信息放入被禁止的「main_Codes」的表變量中,左連接到它並測試爲空...

雖然可以運行執行計劃並查看瓶頸的實際位置,這取決於您自己的環境索引,統計等)...