我已经遇到了无法解释的PARALLEL提示的有趣行为。
实体的层次结构带有一些其他参数,例如-type。查询的想法是:选择没有特定类型的直接和间接子代的所有实体。
数据样本:
create table parallel_hierarchy_test (
"ID" NUMBER(20,0),
"PARENT_ID" NUMBER(20,0),
"TYPE" NUMBER(20,0)
);
insert into parallel_hierarchy_test
select 0, null, 2 from dual
union all
select 1, 0, 2 from dual
union all
select 2, 0, 2 from dual
union all
select 3, 0, 2 from dual
union all
select 4, 1, 2 from dual
union all
select 5, 1, 2 from dual
union all
select 6, 4, 2 from dual
union all
select 7, 6, 1 from dual
union all
select 8, 2, 1 from dual
union all
select 9, 8, 1 from dual;
/* (id, type):
(0, 2)
--(1, 2)
----(4, 2)
------(6, 2)
--------(7, 1)
----(5, 2)
--(2, 2)
----(8, 1)
------(9, 1)
--(3, 2)
*/
而不是我看到的最佳查询:
SELECT /*+ PARALLEL(2) */
t3.id
FROM parallel_hierarchy_test t3
WHERE
t3.id NOT IN (
SELECT t2.id
FROM parallel_hierarchy_test t2
START WITH t2.id IN (
SELECT
t1_2.id
FROM
(SELECT t1.id, t1.type
FROM parallel_hierarchy_test t1
START WITH t1.id = 0
CONNECT BY PRIOR t1.id = t1.parent_id
) t1_2
WHERE t1_2.type = 1)
CONNECT BY PRIOR t2.parent_id = t2.id
);
此脚本但没有并行提示,返回预期的ID:3、5。 但是与之并行时,它将返回所有id:0、1、2、3、4、5、6、7、8、9。 并行执行计划在这里:
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 10 |00:00:02.01 | 9 | | | |
| 1 | PX COORDINATOR | | 1 | | 10 |00:00:02.01 | 9 | | | |
| 2 | PX SEND QC (RANDOM) | :TQ40001 | 0 | 10 | 0 |00:00:00.01 | 0 | | | |
|* 3 | HASH JOIN ANTI NA | | 0 | 10 | 0 |00:00:00.01 | 0 | 2616K| 2616K| 1491K (0)|
| 4 | PX BLOCK ITERATOR | | 0 | 10 | 0 |00:00:00.01 | 0 | | | |
|* 5 | TABLE ACCESS FULL | PARALLEL_HIERARCHY_TEST | 0 | 10 | 0 |00:00:00.01 | 0 | | | |
| 6 | BUFFER SORT | | 0 | | 0 |00:00:00.01 | 0 | 2048 | 2048 | |
| 7 | PX RECEIVE | | 0 | 10 | 0 |00:00:00.01 | 0 | | | |
| 8 | PX SEND BROADCAST | :TQ40000 | 0 | 10 | 0 |00:00:00.01 | 0 | | | |
| 9 | VIEW | VW_NSO_1 | 1 | 10 | 0 |00:00:00.01 | 6 | | | |
|* 10 | CONNECT BY WITH FILTERING (UNIQUE) | | 1 | | 0 |00:00:00.01 | 6 | 1024 | 1024 | |
| 11 | TABLE ACCESS BY INDEX ROWID | PARALLEL_HIERARCHY_TEST | 1 | | 0 |00:00:00.01 | 6 | | | |
| 12 | PX COORDINATOR | | 1 | | 1 |00:00:00.01 | 6 | | | |
| 13 | PX SEND QC (RANDOM) | :TQ30002 | 0 | 10 | 0 |00:00:00.01 | 0 | | | |
|* 14 | HASH JOIN SEMI BUFFERED | | 0 | 10 | 0 |00:00:00.01 | 0 | 2297K| 2297K| 1388K (0)|
| 15 | BUFFER SORT | | 0 | | 0 |00:00:00.01 | 0 | 4096 | 4096 | |
| 16 | PX RECEIVE | | 0 | 10 | 0 |00:00:00.01 | 0 | | | |
| 17 | PX SEND HASH | :TQ30000 | 0 | 10 | 0 |00:00:00.01 | 0 | | | |
|* 18 | VIEW | | 1 | 10 | 3 |00:00:00.01 | 3 | | | |
|* 19 | CONNECT BY NO FILTERING WITH START-WITH| | 1 | | 10 |00:00:00.01 | 3 | 2048 | 2048 | 2048 (0)|
| 20 | PX COORDINATOR | | 1 | | 10 |00:00:00.01 | 3 | | | |
| 21 | PX SEND QC (RANDOM) | :TQ20000 | 0 | 10 | 0 |00:00:00.01 | 0 | | | |
| 22 | PX BLOCK ITERATOR | | 0 | 10 | 0 |00:00:00.01 | 0 | | | |
|* 23 | TABLE ACCESS FULL | PARALLEL_HIERARCHY_TEST | 0 | 10 | 0 |00:00:00.01 | 0 | | | |
| 24 | PX RECEIVE | | 0 | 10 | 0 |00:00:00.01 | 0 | | | |
| 25 | PX SEND HASH | :TQ30001 | 0 | 10 | 0 |00:00:00.01 | 0 | | | |
| 26 | PX BLOCK ITERATOR | | 0 | 10 | 0 |00:00:00.01 | 0 | | | |
|* 27 | TABLE ACCESS FULL | PARALLEL_HIERARCHY_TEST | 0 | 10 | 0 |00:00:00.01 | 0 | | | |
|* 28 | HASH JOIN | | 0 | | 0 |00:00:00.01 | 0 | 1160K| 1160K| |
| 29 | CONNECT BY PUMP | | 0 | | 0 |00:00:00.01 | 0 | | | |
| 30 | TABLE ACCESS FULL | PARALLEL_HIERARCHY_TEST | 0 | 10 | 0 |00:00:00.01 | 0 | | | |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("T3"."ID"="ID")
5 - access(:Z>=:Z AND :Z<=:Z)
10 - access("T2"."ID"=PRIOR NULL)
14 - access("T2"."ID"="T1_2"."ID")
18 - filter("T1_2"."TYPE"=1)
19 - access("T1"."PARENT_ID"=PRIOR NULL)
filter("T1"."ID"=0)
23 - access(:Z>=:Z AND :Z<=:Z)
27 - access(:Z>=:Z AND :Z<=:Z)
28 - access("T2"."ID"=PRIOR NULL)
当然,可以通过其他请求进行选择,但是我想了解为什么上述请求返回带有PARALLEL提示的意外结果。
答案 0 :(得分:0)
使用以下参数之一进行检查:
alter session set "_bloom_filter_enabled" = false;
alter session set "_optimizer_transitivity_retain" = false;
alter session set "_slave_mapping_enabled" = false;
alter session set "hash_join_enabled" = false;
alter session set "_bloom_pruning_enabled" = false;
alter session set "_push_join_union_view" = false;
alter session set "_optimizer_push_pred_cost_based" = false;
我们已经遇到了同样的情况,这是来自oracle的错误,解决该问题的唯一参数是“ hash_join_enabled” = false