接上一篇:
oracle碰到or子查询效率低,三大方法助力性能起飞_part1
oracle碰到or子查询效率低,三大方法助力性能起飞-凯发app官方网站
disjunctive subquery unnest条件,11g支持,由隐含参数_optimizer_unnest_disjunctive_subq控制:
前提必须是:
1)能unnest subquery必须or分支里的主表关联列是同一个列(如果不是关联列,or在子查询外面,且是主表条件,12c可以直接走or expansion subquery),
如果子查询里有or分支且主表和子查询表关联,则主表条件在子查询里位置必须在同一侧(大前提,列做运算,函数都不行)且要同一个列
2)能够转为union all的子查询表对应的列必须类型一致,因为union all要求字段类型一致。
disjunctive subquery查询转换主要有如下形式:
1)or在子查询外面,比如where 【not】exists(suq1) or exp、where 【not】exists(suq1) or 【not】exists(subq2), exists和in一样,子查询分开,可能对应不同表,
2) or在子查询里面,比如where 【not】exists ( condition1 or condition2...),这种同样要满足disjunctive subquery条件才能转换。
针对or在子查询外面的情况:
1.1)一种格式是where exists(suq1) or exp,见or expansion subquery,12c支持,oracle碰到or子查询效率低,三大方法助力性能起飞_part1
1.2) subq1 or subq2形式,需要子查询对应主表列条件来源于同一个表,而且顺序一致,且子查询表类型一致,
因为这个要将子查询表做union all然后变为view,然后再与主表关联,如下示例:
-
select * from a
-
where exists (select 1 from b where a.object_id = b.object_id)
-
or exists (select 1 from c where a.object_id=c.object_id);
这个例子如何subq1 or subq2格式,且主表的列是同一个且在子查询里的条件都在左侧。所以可以
查询转换。
执行计划如下所示,可以看到c和b查询后做成union all视图,并且剔重(按照object_id剔重):
-
execution plan
-
----------------------------------------------------------
-
plan hash value: 2880773727
-
-
----------------------------------------------------------------------------------------
-
| id | operation | name | rows | bytes | cost (%cpu)| time |
-
----------------------------------------------------------------------------------------
-
| 0 | select statement | | 1 | 111 | 1349 (1)| 00:00:17 |
-
| 1 | nested loops | | | | | |
-
| 2 | nested loops | | 1 | 111 | 1349 (1)| 00:00:17 |
-
| 3 | view | vw_sq_1 | 153k| 1949k| 612 (1)| 00:00:08 |
-
| 4 | hash unique | | 1 | 749k| 612 (51)| 00:00:08 |
-
| 5 | union- all| | | | | |
-
| 6 | table access full | c | 76791 | 374k| 306 (1)| 00:00:04 |
-
| 7 | table access full | b | 76791 | 374k| 306 (1)| 00:00:04 |
-
|* 8 | index range scan | idx1_a | 1 | | 1 (0)| 00:00:01 |
-
| 9 | table access by index rowid| a | 1 | 98 | 2 (0)| 00:00:01 |
-
----------------------------------------------------------------------------------------
-
-
predicate information (identified by operation id):
-
---------------------------------------------------
-
-
8 - access("a"."object_id"="vw_col_1")
如果子查询将a.object_id移动到右侧,则不能
disjunctive subquery unnest,不符合主表关联条件在同一侧:
阅读(515) | 评论(0) | 转发(0) |