接上一篇:
ORACLE碰到OR子查询效率低,三大方法助力性能起飞_PART1
1.disjunctive subquery unnest
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,不符合主表关联条件在同一侧:
阅读(1896) | 评论(0) | 转发(0) |