Oracle 查詢轉換 (下)

星型轉換

星型轉換是Oracle用來處理星型連接優化的一種手段。
星型連接(star join)並不是一種額外的連接類型,它是一種單個事實表 (fact table) 和多個維度表(Dimension table)之間的連接。

星型連接的各維度表之間沒有直接的關聯條件,其事實表和維度表之間是基於事實表的外鍵列和對應維度表的主鍵列之間的連接,並且通常在事實表的外鍵列上還會存在對應的位圖索引。

這裏寫圖片描述

SALES 數據量較大,而其他維度表數量比sales小很多。

連接謂詞推入:

連接謂詞推入是優化器處理帶視圖的目標sql的優化手段。

優化器還是會把該sql中定義的視圖作爲一個獨立的處理單元來單獨執行,但此時優化器會把原本處於該視圖外部查詢中和該視圖之間的連接條件推入該視圖的定義sql語句內部,這樣做是爲了能使用上該視圖內部相關基表上的索引,進而能走出基於索引的嵌套循環連接。

由於進行連接謂詞推入後走的嵌套循環連接,那麼就存在外表過大的問題,那麼此時嵌套循環連接的執行效率就可能低於相對應的哈希連接。因此Oracle在做連接謂詞推入時會考慮成本,只有當經過連接謂詞推入後走嵌套循環連接的等價改寫sql的成本值小於原sql的成本值,Oracle纔會對目標對連接謂詞推入。

Oracle是否能做連接謂詞推入與目標視圖的類型、該視圖與外部查詢之間的連接類型以及連接方法有關,到目前爲止,Oracle僅支持如下類型的視圖做連接謂詞推入。

視圖定義sql語句中包含 union all 、union的視圖。
視圖定義sql語句中包含distinct的視圖
視圖定義sql語句中包含group by的視圖
和外部查詢之間的連接類型是外連接的視圖
和外部查詢之間的連接類型是反連接的視圖
和外部查詢之間的連接類型是半連接的視圖

這裏寫圖片描述

連接因式分解:

連接因爲分解是優化器處理帶有union all的目標的sql的一種優化手段。
它是指優化器在處理以union all 連接的目標sql的各個分支時,不在原封不動的分別重複執行每個分支,而是會把各個分支公共的部分提出來作爲一個單獨的結果集,然後再和原union all中剩下的部分做表連接。

即使在視圖定義的sql語句中包含了集合運算符union all而導致Oracle不能對其做視圖合併,Oracle也不一定把該視圖的定義sql語句當作一個整體來單獨執行,因爲此時Oracle還可能會對其做連接因式分解。

表擴展:

是優化器處理針對分區表的目標sql的一種優化手段。
它是指當目標sql中分區表的某個局部分區索引由於某種原因在某些分區上變得不可用,Oracle將原目標sql等價改寫成按分區union all的形式,這樣除了那些不可用的分區所對應的union all分支之外,其他分區所對應的union all分支還是正常使用該局部分區索引。

表移除:

表移除是有優化器處理帶多表連接的目標sql的一種優化手段,它是指優化器會把雖然在目標sql中存在,但是其存在與否對最終的執行結果沒有影響,則這樣的表從視圖中移除。

Oracle處理SQL語句中的IN

優化器處理帶in的目標sql時,通常會採用如下四種方法:
使用in-List Iterator
使用 in-List Expansion
使用in-list filter
對In做子查詢展開,或者即做子查詢展開,又做視圖合併。

IN-List Iterator是針對in後面是常量集合的一種處理方法。
In-list Iterator的效率通常比in-list Expansion 高。
對應的列上必須有索引
Oracle不能強制sql走in-list Iterator類型的執行計劃。

In-List Expansion是針對IN後面是常量集合另一種處理方法。它是指優化器會把目標sql中in後面的常量集合拆開,把裏面的每個常量都提出來形成一個分支,各分支之間用union all來連接。

IN-List Expansion的好處是,改寫成union all的連接的分支後,各個分支就可以走各自的索引,分區修剪,表連接等相關的執行計劃而不互相干擾。
它的壞處是未做In-List Expansion之前優化器只需要解析一個目標sql,做了IN-List Expansion之後,就需要對每個分支做解析

因此 in後面的常量比較多的時候,In-list Expansion的解析時間就會增多。

如果in的後面常量比較多的情況下可以採用下面的方法來處理:
使用no_expand hint 不讓CBO走IN-List Expansion的執行計劃。
將in的常量放在一箇中間表裏面。此時in後面就不再是常量了。

In-list Filter
這個是Oracle處理in後面子查詢的方式。在子查詢裏面已經解釋過。

對in做子查詢展開、視圖合併

能對IN做子查詢展開/視圖合併,意味着目標sql要滿足如下前提條件:

1、 目標sql的in後面不再是子查詢而是常量集合。
2、 Oracle能對目標sql 的in後面的子查詢做子查詢展開。

上述第二點可以細分如下幾種情況:
in後面的子查詢不包含視圖,只進行子查詢展開。
in後面的子查詢包含視圖,但是不能進行視圖合併,此時也只能進行子查詢展開。
in後面的子查詢包含視圖,可以進行視圖合併,此時Oracle即做視圖合併,又做子查詢展開。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章