查詢優化 In Oracle


 

Cost-based query transformation in Oracle

Enhanced Subquery Optimizations in Oracle

 

Cost-based query transformation in Oracle

本文介紹Oracle的查詢優化框架,

先描述,Oracal分別在RBO和CBO做了哪些事情,為什么要這樣做

 

Heuristic Transformation

先看下RBO的部分,RBO部分的Rule基本都是確定可以帶來優化的

Subquery Unnesting

子查詢消除,子查詢如果用apply的方式的話,文中稱TIS,Tuple iteration semantics,基本等同於nested loop方式,比較低效

消除的方法分成兩大類,

1. 把子查詢 merge 到外部查詢里面去

如下面的例子,把exists變成semi-join

2. 產生inline views,或derived table的方式,這種方式會放到CBO里面,所以后面給出例子

 

Join Elimination

消除無用的Join

其中Q4,dept_id是foreign key,所以每個employee都必須有一個dept,這里join起不到filter的作用

 

Filter Predict Move Around 

Filter下推,盡早的過濾數據,前提是這里的Filter是inexpensive的

 

Group Pruning

刪掉在外層查詢中不需要的group

下面的例子,在外層查詢中,過濾city,那么city其實就決定了state,country,子查詢中的group by 就沒有必要了

 

Cost-Based Transformations 

這里講到重點,看下哪些Transformation應該在CBO里面去做的

Subquery Unnesting

第一個仍然是子查詢消除,前面說了,如果是產生inline view的方式,需要用CBO

下面的例子,從Q1到Q10,產生了inline view或派生表 V

這里產生inline view的方式不一定會比nested loop的方式更好,如果filter出的row很少,而索引建的很好,很可能nested loop的方式更優

所以這種不確定的情況下,需要CBO來判斷

 

Group-by and Distinct View Merging

右稱為,Groupby Pull-up,如果join會大幅降低數據量,那么把groupby上提是核算的,因為groupby一般都是聚合,比較expensive的操作

比如下面Q11的例子,

把計算平均salary的inline view,挪到了外部查詢的group by

可以看到把group by移到外面后,group by的field需要加上join key

Group-by Placement

對應於上面說的Pull Up,這里是Push Down

 

 

Join Predicate Pushdown

把外部查詢的join predicate下推到子查詢中,

一般套路都是uncorrelation,這里反之,不是所有情況都可以這樣下推

 

例子,

 

Join Factorization

 將公共的 join tables 上提

 

Predicate Pullup

將Expensive的Predicate進行上提,

 

Set Operator Into Join

 

Disjunction Into Union All

 

Framework For Cost-based Transformation

State Space Search Tech

CBO有個關鍵的問題是,如果Transformation持續變多,那么搜索空間是成指數級別上升的

針對這樣的問題,比較可行的方式是引入隨機算法,

Oracle的搜索算法如下,

Exhaustive,窮盡法

Iterative,局部最優,每次選擇不同的初始點,有點像退火

Linear,動態回歸

Two-pass,強行降低搜索空間

 然后這里比較有借鑒意義,針對不同的search規模,我們應該選用不同的搜索算法

 

Transformation執行的方式

Oracle中按照順序的方式去執行Transformations,

這里給出各個分類的執行順序

當然有些情況下光順序執行是不夠的,

3.3里面提到了,

Interleaving方式,有些rule需要交叉的執行

舉得例子是,Unnesting和View merging

Juxtaposition的方式,

 

Enhanced Subquery Optimizations in Oracle

本文討論Oracle對於子查詢的優化方法

Subquery Coalescing

子查詢合並,把多個子查詢合並成一個

這里提出,Container和Contained的概念

直觀上,如果A contain B

A and B,就可以remove A

A or B,就可以removeB

 

Coalescing Subqueries of The Same Type

SameType,類型一樣,要不都是Exist,要不都是Not Exist

和上面說的一致,只是這里加上Exist和Not Exist,有點繞

總之conjunction留小的,contained,disjunctive留大的,container

 

對於不滿足Containment Property的子查詢,仍然可能進行coalescing,

只要他們除了filter和predicates以外是equivalent的

這個很直觀,因為如果只是Predicate不一樣,是可以合並的

例子,雖然沒有containment關系,但是僅僅只有predict不一樣

 可以看到,可以直接把Exists間的OR,轉化為predict之間的OR,很直覺

 

Coalescing Subqueries of Different Type 

不同的Type,Exist和Not Exist之間的

可以看TPC-H的Q21,

兩個子查詢是滿足Containment關系的,但是類型不一樣

這里的感覺就要從Container中挖去Contained的那塊

是這樣轉換的,

用Having,對滿足條件的case求sum,然后過濾,好tricky

 

Coalescing and Other Transformations

Q5加上外層的Join就是Q6

這里做的轉換是,View merging,就是Groupby Pullup

但是GroupBy的Pull up還是Push down,需要通過cost-based來決定

 

 

Subquery Removal Using Window Functions

Oracle有窗口函數,可以用於替換子查詢,論文里說,對於TCP-H,性能會有10倍提升

這里有subsume的概念,outer query包含子查詢中的所有tables和predicates

 這個例子,滿足Subsume關系,在子查詢中主要為了做AGG

 所以這里用窗口函數就可以簡單的remove掉子查詢

 

Correlated Subsumed Subquery

相關子查詢,在TCP-H中的代表是Q2,Q17

 Q2,子查詢中主要為了求min

用窗口函數,改造后

對於Q17,微軟提出的是SegmentApply的方案,這里用窗口函數改造后,

底下關於Duplicate rows,沒太懂

說是窗口函數必須within a view,沒看出和上面的區別

 

Uncorrelated Subsumed Subquery

非相關子查詢,TCP-H,Q15 

用窗口函數轉化為,因為是非相關子查詢,所以OVER里面是空的,不需要PBY

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM