查询会根据PARALLEL提示返回不同的结果

时间:2019-03-21 05:35:47

标签: sql database oracle oracle12c hierarchy

我已经遇到了无法解释的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提示的意外结果。

1 个答案:

答案 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