2015-07-01 51 views
1

什麼是使用一個連接的ON子句中像這樣利用2個謂詞與OR性能的影響:性能比較加入1個謂詞每個

SELECT GS.GuitarType,GD,GuitarColor 
FROM Prod.Guitars GS 
LEFT JOIN Prod.Guitar_Detail GD ON (GS.GuitarID = GD.GuitarID OR GS.GuitarID = GD.GuitarCatNum) 

VS.是這樣的:

SELECT GS.GuitarType,GD,GuitarColor 
FROM Prod.Guitars GS 
LEFT JOIN Prod.Guitar_Detail GD ON GS.GuitarID = GD.GuitarID 
LEFT JOIN Prod.Guitar_Detail GD2 ON GS.GuitarID = GD.GuitarCatNum 

夫婦的注意事項: 我們必須使用LEFT JOIN不能使用INNER。 我已經跑了兩個查詢,後者表現更好。

還有一個問題,第二個不會返回更多的行嗎?因爲它們都在同一張桌子上加入,所以它們都應該只保留GS表格?

在第一個查詢中,它是否必須匹配兩次?或者爲什麼它的表現與第二種不同?

+0

如果有1對1的關係,你會得到相同的行數。 – jarlh

+0

'Guitar_Detail'表的主鍵是什麼? –

+0

注意在第二個查詢中,您從不會從第二次連接獲取任何數據。 – HLGEM

回答

3

讓我以相反的順序回答。

另外一個問題,第二個不會返回更多的行嗎? 因爲他們都在同一張桌子上加入,他們 都應該只保留GS表正確嗎?

查詢是不同的(差異在於如何處理空值),並且應該預期不同的執行時間。一切都歸結爲如何使用GD.GuitarID和GD.GuitarCatNum。 a)如果GD.GuitarID被設置並且GD.GuitarCatNum爲空,則查詢將返回相同的數據。
b)如果設置GD.GuitarID並且GD.GuitarCatNum包含與GD.GuitarID相同的值,則第二個查詢將返回重複的行。
c)如果GD.GuitarID爲空且設置了GD.GuitarCatNum,則查詢將返回相同數量的行,但GD.GuitarColor將返回爲null。現在

,假設情況下),執行計劃是這樣的:

案例1)

SELECT 
    GS.GuitarType, 
    GD.GuitarColor 
FROM 
    Guitars GS 
    LEFT JOIN Guitar_Detail GD 
    ON (GS.GuitarID = GD.GuitarID OR 
     GS.GuitarID = GD.GuitarCatNum) 

Access Plan: 
----------- 
    Total Cost:   18.3602 
    Query Degree:  1 

       Rows 
      RETURN 
      ( 1) 
       Cost 
       I/O 
       | 
       3 
      >NLJOIN 
      ( 2) 
      18.3602 
       2 
     /-----+------\ 
     2    1.5 
    TBSCAN   TBSCAN 
    ( 3)   ( 4) 
    8.99536   9.07676 
     1    1 
     |    | 
     2    2 
TABLE: DB2INST1 TABLE: DB2INST1 
    GUITARS  GUITAR_DETAIL 
     Q2    Q1 

案例2)

SELECT 
    GS.GuitarType, 
    GD.GuitarColor 
FROM 
    Guitars GS 
    LEFT JOIN Guitar_Detail GD 
    ON GS.GuitarID = GD.GuitarID 
    LEFT JOIN Guitar_Detail GD2 
    ON GS.GuitarID = GD.GuitarCatNum 

    Total Cost:   27.2798 
    Query Degree:  1 

           Rows 
           RETURN 
           ( 1) 
           Cost 
           I/O 
           | 
           2 
           >NLJOIN 
           ( 2) 
           27.2798 
           3 
       /--------------+---------------\ 
       2         1 
      HSJOIN<       NLJOIN 
      ( 3)        ( 6) 
      18.0326       9.01796 
       2         1 
     /-----+------\      /-----+------\ 
     2    2    0.5    2 
    TBSCAN   TBSCAN   TBSCAN   TBSCAN 
    ( 4)   ( 5)   ( 7)   ( 8) 
    8.99536   8.99536   0.0226   8.99536 
     1    1     0    1 
     |    |     |    | 
     2    2     1    2 
TABLE: DB2INST1 TABLE: DB2INST1 TABFNC: SYSIBM TABLE: DB2INST1 
    GUITAR_DETAIL  GUITARS   GENROW  GUITAR_DETAIL 
     Q2    Q1    Q4    Q6 

希望這有助於。

1

或通常在連接中表現不佳。最好設計你的數據庫,這樣你就不需要這些類型的連接。但是,我們都有時會遇到設計問題,在這種情況下,使用UNION ALL(如果兩個連接字段互相交錯)通常更具有高性能。如果字段不相互排斥,並且您不想重複,則聯盟會更慢但更好。