2013-01-19 116 views
2

我有一個相當長的(10個表,每個約60K條記錄)查詢,所有這些表都使用左連接進行連接,因爲它們可以包含空值(全部)。改進/優化SQL Server中的LEFT JOIN

我看到一個巨大的性能打擊,我追蹤到這一點的代碼。

SELECT * 
FROM MAIN_TABLE d 
LEFT JOIN INSURANCES i on i.IMREDEM_CODE = d.IMREDEM_CODE 
         and i.INS_TERMINATIONDATE IS NULL 
         and INS_RANK = 0 
         and i.IMREINS_CODE = (SELECT TOP 1 IMREINS_CODE 
               from INSURANCES i2 
              WHERE i2.IMREDEM_CODE = i.IMREDEM_CODE 
               and i2.INS_TERMINATIONDATE IS NULL 
               and i2.INS_RANK = 0 
              ORDER BY TAG_SYSTEMDATE DESC) 

基本上什麼,我需要做的是,保險表可以包含0或者多條記錄,因爲當他們更新保險它執行插入不爲審計目的的更新。所以我必須在左邊加入兩次表格。此外,我需要爲主保險和第二保險兩次執行此查詢(主要級別= 0,次級級別= 1。IMREDEM_CODE是D表和FK的I表

答案在這裏

left join INSURANCES i on i.IMREDEM_CODE = d.IMREDEM_CODE 
and i.IMREINS_CODE = (SELECT max(imreins_code) FROM INSURANCES i2 WHERE i2.IMREDEM_CODE = i.IMREDEM_CODE and i2.INS_TERMINATIONDATE IS NULL and i2.INS_RANK = 0) 
+0

http://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql-server/ –

+0

你對保險有哪些指標表? – Laurence

回答

2

雖然我敢肯定,你可能能夠進一步優化這一點,我已經採取快速刺傷它一個會做3個表掃描。你可以試試這個,這將減少到2:

SELECT * 
FROM Main_Table d 
    LEFT JOIN 
     (SELECT TOP 1 * 
     FROM Insurances 
     WHERE INS_TERMINATIONDATE IS NULL 
      AND INS_RANK = 0 
     ORDER BY TAG_SYSTEMDATE DESC) i on i.IMREDEM_CODE = d.IMREDEM_CODE; 

有可能比TOP 1和ORDER BY一個更好的方法,但我累了,此刻也沒有想起來。無論哪種方式,這絕對是更有效率。

以下是有兩組查詢的SQL Fiddle。你可以看到每個執行計劃。

祝你好運。

+0

謝謝,我添加了這個,並測試了查詢,採取1:56拉回100行。它使用另一種方法0:03(基本上用max()表達式執行WHERE IN - 這被證明是關鍵的,而不是返回一堆行,然後按日期排序,插入的最後一個(最高標識值)是總是最近的,我忘記了。 – Rob

+0

是的,我覺得有一個比Order by和Top 1更好的方法 - 只是漫長的一天:-)很高興我能提供幫助。 – sgeddes

1

我相信下面會給你完全相同的結果,但速度更快;

SELECT * 
    FROM MAIN_TABLE d 
LEFT JOIN INSURANCES i on i.IMREDEM_CODE = d.IMREDEM_CODE 
         and i.IMREINS_CODE = select max(i.imreins_code) from INSURANCES 
         and i.INS_TERMINATIONDATE IS NULL 
         and i.INS_RANK = 0 
+0

這不適用於SQL Server。這裏是小提琴:http://sqlfiddle.com/#!3/8694e/9 - 最大不會像這樣工作 – sgeddes

+0

基本上你不能把MAX()放在這樣的查詢中,但是我結束了(再次做4個表掃描)LEFT JOIN保險我在....和i.IMREINS_CODE =選擇MAX(imreins_code從保險i2在哪裏....)這使查詢時間從6秒減少到4-5秒:30。 – Rob