Oracleのクエリの最適化で

Oracleでコストベースの問合せ変換

Oracleで強化されたサブクエリの最適化

 

Oracleでコストベースの問合せ変換

この記事では、Oracleのクエリの最適化の枠組みを説明し、

最初に行われていたものRBOとCBOそれぞれ、Oracalを説明し、なぜ行います

 

ヒューリスティック変換

RBO、RBOルール]セクションの下の部分を見ては、基本的に決定され、最適化をもたらすことができます

副問合せのネスト解除

サブクエリがサブクエリ場合、次に方法を適用し、排除し、紙はTIS、ネストされたループ・モードと基本的に同等の比較的非効率的なタプル反復セマンティクスは、前記しました

2つのカテゴリに分ける除去する方法、

1.外側のクエリ内で行くことにクエリマージを扱います

次の例、に存在する半結合

2.インライン・ビュー、または派生テーブル方式を生成し、本実施形態では、CBOの内部に置かれ、後者の例が与えられます。

 

除去に参加

無用排除しましょう

どのQ4、DEPT_ID外部キーであるので、各従業員がDEPTを持っている必要があり、ここでは何の効果がフィルターに参加していません

 

予測フィルタ動き回ります 

フィルタは、できるだけ早くデータをフィルタリングし、押し下げここフィルターが安価であることを提供しました

 

グループ剪定

外側のクエリグループ内の不要な削除

次の例では、外側のクエリ、濾過都市で、その後都市は実際には必要ないことで州、国、サブクエリグループを決定します

 

コストベースの変換 

ここでは内部の変換CBOに何をすべきかを見て、焦点の話

副問合せのネスト解除

最初のサブクエリがまだそれはインライン・ビューを生成する方法であれば、CBOを使用する必要があり、先に述べた、除去され

Q1からQ10、生成または抽出テーブルインラインビュー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来决定

 

 

 

 

 

 

 

 

 

おすすめ

転載: www.cnblogs.com/fxjwind/p/11420589.html