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即做视图合并,又做子查询展开。

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