2011-11-09 42 views
1

背景:爲什麼innerjoin的where子句中的這個小sql更改會導致巨大的性能提升?

我們將ERP中的一些性能問題縮減爲一條SQL語句。我們的支持人員對SQL語句和性能進行了一點改動。後端是Microsoft Access。 (是的,我知道,是的,這是尷尬的,沒有我在這件事上沒有選擇)

我們從75%的時間聲明需要90秒運行,25%2-3秒到100%時間2-3秒。

POHDR表大20,000加行,SUPPNAME小於1000.兩個表都有vnum字段索引。

下面的SQL語句,但所有改變的是Where子句使用SUPPNAME.vnum而不是POHDR.vnum。

BEFORE:

SELECT DISTINCTROW POHDR.*, 
        SUPPNAME.SNAME1, 
        suppname.sname1 & chr(13) & chr(10) & POHDR.vnum as SUPPFLD 
    FROM POHDR 
     INNER JOIN SUPPNAME 
      ON POHDR.VNUM = SUPPNAME.VNUM 
    WHERE ((POHDR.VNUM= '20023' AND POHDR.RECDATE Is Null)) 
     AND [POHDR].[CANCEL] Is Null and ((POHDR.CLOSED=No)) 
    order by IIf(InStr(PO,'-'),Left(PO,InStr(PO,'-')) & '_' & Mid(PO,InStr(PO,'-')),PO) 

AFTER:

SELECT DISTINCTROW POHDR.*, 
        SUPPNAME.SNAME1, 
        suppname.sname1 & chr(13) & chr(10) & POHDR.vnum as SUPPFLD 
    FROM POHDR 
     INNER JOIN SUPPNAME 
      ON POHDR.VNUM = SUPPNAME.VNUM 
    WHERE ((SUPPNAME.VNUM= '26037' AND POHDR.RECDATE Is Null)) 
     AND [POHDR].[CANCEL] Is Null 
     and ((POHDR.CLOSED=No)) 
    order by IIf(InStr(PO,'-'),Left(PO,InStr(PO,'-')) & '_' & Mid(PO,InStr(PO,'-')),PO) 

是否改變,其中vnum選擇到一個較小的表少用或不用的vnum重複真正使這麼大的差異,或還有其他事情嗎?

謝謝,布賴恩好奇。

p.s.另外,我沒有編寫或控制這個sql語句。而且不清楚按順序排列的if語句到底是怎麼回事。

+0

Google「JETSHOWPLAN」。運行每個查詢並比較Showplan.out文件中的結果。在這裏發佈結果作爲你問題的一部分(如果他們仍然對你沒有意義)或作爲答案(如果你明白髮生了什麼,並希望與我們其他人分享)。 – mwolfe02

+0

當你這樣做時,你可能還想嘗試第三個查詢:'...從POHDR,SUPPNAME WHERE POHDR.VNUM ='26037'和SUPPNAME.VNUM ='26037'...' – mwolfe02

+0

當然,我們理所當然地認爲POHDR.VNUM和SUPPNAME.VNUM都被編入索引...是否還有其他一些限制,如唯一值等? –

回答

0

我不知道你的問題是否有一個很好的「WHY」答案,除了改變WHERE子句導致優化器選擇不同的查詢計劃這一事實。

優化器可以根據許多因素(索引,統計數據,黑魔法等)來選擇查詢計劃。只要你有好的索引,你通常能做的最好的就是仔細測試不同類型的查詢,並比較它們生成的查詢計劃。

0

這種查詢優化的關鍵是索引 - 首先要檢查是否所有字段都被索引,特別是SUPPNAME.VNUM和POHDR.VNUM。

然後,第二個當然是每個表中滿足這些條件的記錄數。如果只有一個SUPPNAME.VNUM ='26037',它可以消除大量的POHDR.VNUM ='20023',這將在其他標準上失敗,然後不需要執行。

但是沒有看到你的數據庫和數據的結構,我不會做出任何明確的結論。

相關問題