選取最佳結合的策略

最佳化工具使用各種方法來選取查詢的最佳結合策略。 這些方法由查詢的最佳化類別決定,其中包括數個搜尋策略、星狀綱目結合、早期輸出結合及複合表格。

結合列舉演算法是最佳化程式所探索的計劃組合數目的重要決定因素。
  • 窮盡結合列舉
    • 在空間和時間需求方面有效率
    • 使用單一方向列舉; 亦即,針對兩個表格選取結合方法之後,在進一步最佳化期間不會變更它
    • 結合多個表格時可能會錯過最佳存取方案。 如果查詢只結合兩個或三個表格,則貪婪結合列舉所選擇的存取計劃與動態程式設計結合列舉所選擇的存取計劃相同。 如果查詢在相同直欄上具有許多明確指定的結合述詞,或透過述詞轉移閉包隱含產生的結合述詞,則尤其如此。
  • 動態程式設計結合列舉
    • 在空間和時間需求方面效率不高,這隨著結合表格數目增加而呈指數增長
    • 在搜尋最佳存取計劃時有效率且詳盡
    • 類似於 Db2® for z/OS® 所使用的策略

星狀綱目結合

查詢中所參照的表格幾乎一律以結合述詞相關。 如果在沒有結合述詞的情況下結合兩個表格,則會形成兩個表格的笛卡兒乘積。 在笛卡兒乘積中,第一個表格的每一個合格列與第二個表格的每一個合格列結合。 這會建立通常非常大的結果表格,因為其大小是兩個來源表格大小的交叉乘積。 因為這類計劃不太可能執行良好,所以最佳化工具甚至會避免判定這類存取計劃的成本。

當最佳化類別設為 9 時,或在星狀綱目的特殊情況下,只會發生異常狀況。 星狀綱目 包含稱為 事實表格的中央表格,以及稱為 維度表格的其他表格。 不論查詢為何,維度表格只有單一結合可將它們附加至事實表格。 每一個維度表格都包含其他值,可展開事實表格中特定直欄的相關資訊。 一般查詢由多個本端述詞組成,這些述詞參照維度表格中的值,並包含將維度表格連接至事實表格的結合述詞。 對於這些查詢,在存取大型事實表格之前,計算多個小型維度表格的笛卡兒乘積可能很有用。 當多個結合述詞符合多直欄索引時,此技術非常有用。

Db2 資料伺服器可以辨識對資料庫的查詢,這些資料庫設計為具有至少兩個維度表格的星狀綱目,並且可以增加搜尋空間以包括計算維度表格的笛卡兒乘積的可能計劃。 在笛卡兒乘積具體化之前,會先考量鋸齒結合。 它會使用多直欄索引來探測事實表格,以便同時沿著兩個以上維度表格來過濾事實表格。 當使用鋸齒結合時,它會傳回事實表格索引中可用的下一個值組合。 這個下一個值組合(稱為回饋)可用來跳過維度表格的卡氏乘積所提供,而在事實表格中找不到相符項的探測值。 同時過濾兩個以上維度表格上的事實表格,以及跳過已知沒有結果的探測,一起使得鋸齒結合成為用於查詢大型事實表格的一種有效方法。

此星狀綱目結合策略假設在結合中使用主要索引鍵索引。 另一個實務範例涉及外部索引鍵索引。 如果事實表格中的外部索引鍵直欄是單一直欄索引,且所有維度表格之間的選擇性相對較高,則可以使用下列星狀綱目結合技術:
  1. 處理每一個維度表格的方式:
    • 在事實表格上維度表格與外部索引鍵索引之間執行半結合
    • 雜湊記錄 ID (RID) 值以動態建立點陣圖
  2. 對於每一個點陣圖,針對前一個點陣圖使用 AND 述詞。
  3. 在處理最後一個點陣圖之後,決定現存的 RID。
  4. 選擇性地排序這些 RID。
  5. 提取基本表格列。
  6. 將事實表格與其每一個維度表格重新結合,以存取維度表格中 SELECT 子句所需的直欄。
  7. 重新套用殘差述詞。

此技術不需要多直欄索引。 不需要事實表格與維度表格之間的明確參照完整性限制,但建議使用。

星狀綱目結合技術所建立及使用的動態點陣圖需要排序資料堆記憶體,其大小由 sortheap 資料庫配置參數指定。

提早輸出結合

當最佳化工具偵測到其中一個表格中的每一列僅需要與另一個表格中的最多一列結合時,可能會選取提早輸出結合。

當其中一個表格的一或多個索引鍵直欄上有結合述詞時,可以提早輸出結合。 例如,假設下列查詢傳回員工及其直屬經理的名稱。
   select employee.name as employee_name,
       manager.name as manager_name
     from employee as employee, employee as manager
     where employee.manager_id = manager.id
假設 ID 直欄是 EMPLOYEE 表格中的索引鍵,且每個員工最多只有一個管理員,則此結合可避免在 MANAGER 表格中搜尋後續的相符列。
當查詢中有 DISTINCT 子句時,也可以進行提早輸出結合。 例如,假設下列查詢會傳回汽車製造商的名稱,這些汽車製造商的型號售價超過 30000 美元。
   select distinct make.name
     from make, model
     where
       make.make_id = model.make_id and
       model.price > 30000
對於每一個汽車製造商,您只需要判斷其任何製造型號的售價是否超過 30000 美元。 加入汽車製造商與其所有製造型號的售價超過 30000 美元的行列是不必要的,因為它不會影響查詢結果的正確性。
當結合饋送具有 MIN 或 MAX 聚集函數的 GROUP BY 子句時,也可以提早輸出結合。 例如,請考量下列查詢,它會傳回最近日期早於 2000 年的股票符號,其特定股票的收盤價至少比其底價高出 10%:
   select dailystockdata.symbol, max(dailystockdata.date) as date
     from sp500, dailystockdata
     where
       sp500.symbol = dailystockdata.symbol and
       dailystockdata.date < '01/01/2000' and
       dailystockdata.close / dailystockdata.open >= 1.1
     group by dailystockdata.symbol
限定集 是 DAILYSTOCKDATA 表格中的列集,可滿足日期和價格需求,並結合 SP500 表格中的特定股票符號。 如果 DAILYSTOCKDATA 表格中的限定集 (針對 SP500 表格中的每一個股票符號列) 在 DATE 排序為遞減,則只需要從限定集傳回每一個符號的第一列,因為該第一列代表特定符號的最新日期。 不需要限定集中的其他列。

複合表格

當結合一對表格的結果是新表格 (稱為 複合表格) 時,此表格通常會變成與另一個內部表格結合的外部表格。 這稱為 複合外部結合。 在某些情況下,特別是在使用貪婪結合列舉技術時,將結合兩個表格的結果變成稍後結合的內部表格非常有用。 當結合的內部表格包含結合兩個以上表格的結果時,此計劃稱為 複合內部結合。 例如,請考量下列查詢:
   select count(*)
     from t1, t2, t3, t4
     where
       t1.a = t2.a and
       t3.a = t4.a and
       t2.z = t3.z

結合表格 T1 和 T2 (T1xT2) ,然後結合 T3 和 T4 (T3xT4) ,最後選取第一個結合結果作為外部表格,並選取第二個結合結果作為內部表格。 在最終計劃 ((T1xT2) x (T3xT4)) 中,結合結果 (T3xT4) 稱為 複合內部結合。 視查詢最佳化類別而定,最佳化工具會對可作為結合內部表格的最大表格數設定不同的限制。 最佳化類別 5、7 及 9 容許複合內部結合。