2016-03-10 58 views
0

下面顯示的查詢花費了將近2小時的時間運行,我想減少此查詢的執行時間。任何幫助對我都會有幫助。SQL加入花費太多時間運行

目前:

If Exists (Select 1         
      From PRODUCTS prd         
      Join STORE_RANGE_GRP_MATCH srg On prd.Store_Range_Grp_Id = srg.Orig_Store_Range_Grp_ID   
              And srg.Match_Flag = 'Y' 
              And prd.Range_Event_Id = srg.LAR_Range_Event_Id 
      Where srg.Range_Event_Id Not IN (Select distinct Range_Event_Id 
              From Last_Authorised_Range) 
     )  

我試圖通過Not ExistsLeft join但在運行時執行沒有運氣更換Not IN條款。

我所用:

If Exists( Select top 1 *       
     From PRODUCTS prd        
     Join STORE srg        
     On prd.Store_Range_Grp_Id = srg.Orig_Store_Range_Grp_ID         
     And srg.Match_Flag = 'Y'         
     And prd.Range_Event_Id = srg.LAR_Range_Event_Id 
and   srg.Range_Event_Id ='45655'   



Where NOT EXISTS (Select top 1 *         
     From Last_Authorised_Range where Range_Event_Id=srg.Range_Event_Id)        
) 

Product表有432837條記錄和Store表還具有幾乎相同數量的記錄。這個表我在存儲過程本身中創建,然後在存儲過程中最後刪除它。

Create Table PRODUCTS         
(        
    Range_Event_Id int,         
    Store_Range_Grp_Id int,         
    Ranging_Prod_No nvarchar(14) collate database_default, 
    Space_Break_Code nchar(1) collate database_default 
)      

Create Clustered Index Idx_tmpLAR_PRODUCTS 
    ON PRODUCTS (Range_Event_Id, Ranging_Prod_No, Store_Range_Grp_Id, Space_Break_Code) 

我應該在這個表上使用非聚集索引還是我可以做什麼來減少執行時間?在此先感謝

+0

「產品」中的「PRIMARY KEY」在哪裏? – Lankymart

+0

將「從Last_Authorised_Range中選擇不同Range_Event_Id 」的結果放在表變量中並且不存在。 – artm

+1

刪除'top 1'和/或'distinct'子句 - exists()'和'in()'沒有這些效果會更好。你可以使用'select *'而不是'select 1' - 更好的可讀性; SQL優化器爲這些生成相同的查詢計劃。在所有ID字段上創建索引。 – Arvo

回答

0

首先,你不需要top 1distinctexistsin子查詢。但這不應該影響性能。

這是查詢,略微重新安排這樣我就可以更好地理解它:

Select 1       
From PRODUCTS prd Join 
    STORE srg        
    On prd.Store_Range_Grp_Id = srg.Orig_Store_Range_Grp_ID and 
     prd.Range_Event_Id = srg.LAR_Range_Event_Id        
Where srg.Match_Flag = 'Y'         
     srg.Range_Event_Id = 45655 and 
Where NOT EXISTS (Select 1         
        From Last_Authorised_Range lar 
        where lar.Range_Event_Id = srg.Range_Event_Id)        
       ) 

確實注意到我刪除周圍45655雙引號。我認爲這一列實際上是一個數字。如果是這樣,不要通過使用字符串進行比較來混淆自己和優化器。

然後,嘗試索引。我認爲最好的指標是:

  • store(Range_Event_Id, Match_Flag, Orig_Store_Range_Grp_ID, LAR_Range_Event_Id)
  • products(Store_Range_Grp_Id, Range_Event_Id)(或任何索引,聚集或以其他方式,與這兩列以任何順序開始)
  • Last_Authorised_Range(Range_Event_Id)

從你描述爲數據量,你的查詢不應該花費數小時。我認爲索引可以提供幫助。

+0

我也使用過索引,並通過刪除Not In Clause來實現左外連接,但它仍然需要2小時才能運行。 –

+0

截至目前,我正在使用所有正在使用的表上的聚簇索引,我應該更改聚簇索引到非聚簇?如果是,爲什麼? –

+0

@SumitDwivedi。 。 。你已經嘗試了這個答案中提到的索引? –