Запрос возвращает разные результаты в зависимости от подсказки PARALLEL - PullRequest
0 голосов
/ 21 марта 2019

Я столкнулся с интересным поведением ПАРАЛЛЕЛЬНОЙ подсказки, которую я пока не могу объяснить.

Существует иерархическая структура сущностей с некоторыми дополнительными параметрами, например - тип. Идея запроса: выбрать все объекты, которые не имеют прямых и косвенных потомков определенного типа.

Образец данных:

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
  );

Этот скрипт, но без параллельной подсказки, возвращает ожидаемые идентификаторы: 3, 5. Но параллельно он возвращает все идентификаторы: 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 голосов
/ 21 марта 2019

Проверьте с одним из этих параметров:

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;

Мы уже столкнулись с тем же, это была ошибка от оракула, и единственным параметром, который решал эту проблему, было "hash_join_enabled" = false

...