Oracle mechanics

14.09.2016

Параллельное выполнение UNION ALL PUSHED PREDICATE и проблемы фиксации параллельных планов

Filed under: heuristics,Oracle,Plan Management,Scripts — Игорь Усольцев @ 19:24
Tags: ,

I. Параллельное выполнение UNION ALL PUSHED PREDICATE

Иногда имеет смысл параллельное выполнение запроса с операцией UNION ALL PUSHED PREDICATE в плане, и если в 11g эту комбинацию воспроизвести просто — и на простом тесткейсе это выглядит так:

11.2.0.3.SCOTT@ SQL> select --+ PARALLEL(4) PUSH_PRED(d)
  2  * from scott.emp e,
  3        (select * from scott.dept
  4         union
  5         select * from scott.dept) d
  6  where d.deptno = e.deptno
  7    and e.job = 'SALESMAN'
  8  /

4 rows selected.

---------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |          |     7 |   476 |     5  (20)| 00:00:01 |        |      |            |
|   1 |  PX COORDINATOR                   |          |       |       |            |          |        |      |            | -- параллельное выполнение
|   2 |   PX SEND QC (RANDOM)             | :TQ10000 |     7 |   476 |     5  (20)| 00:00:01 |  Q1,00 | P->S | QC (RAND)  |
|   3 |    NESTED LOOPS                   |          |     7 |   476 |     5  (20)| 00:00:01 |  Q1,00 | PCWP |            |
|   4 |     PX BLOCK ITERATOR             |          |       |       |            |          |  Q1,00 | PCWC |            |
|*  5 |      TABLE ACCESS FULL            | EMP      |     3 |   114 |     2   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|   6 |     VIEW                          |          |     1 |    30 |     4  (50)| 00:00:01 |  Q1,00 | PCWP |            |
|   7 |      SORT UNIQUE                  |          |     2 |    40 |     4  (75)| 00:00:01 |  Q1,00 | PCWP |            |
|   8 |       UNION ALL PUSHED PREDICATE  |          |       |       |            |          |  Q1,00 | PCWP |            | -- операция UNION ALL PUSHED PREDICATE
|   9 |        TABLE ACCESS BY INDEX ROWID| DEPT     |     1 |    20 |     1   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|* 10 |         INDEX UNIQUE SCAN         | PK_DEPT  |     1 |       |     0   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|  11 |        TABLE ACCESS BY INDEX ROWID| DEPT     |     1 |    20 |     1   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|* 12 |         INDEX UNIQUE SCAN         | PK_DEPT  |     1 |       |     0   (0)| 00:00:01 |  Q1,00 | PCWP |            |
---------------------------------------------------------------------------------------------------------------------------

Note
-----
   - Degree of Parallelism is 4 because of hint

, то в Oracle 12c (возможно, как рез-т исправления Bug 14217009 : WRONG RESULTS FROM PARALLEL QUERY USING UNION ALL и ему подобных?) аналогичную операцию UNION ALL PUSHED PREDICATE уже не так просто заставить выполняться параллельно:

12.1.0.2.@ SQL> select --+ PARALLEL(4) PUSH_PRED(d)
  2  * from scott.emp e,
  3        (select * from scott.dept
  4         union
  5         select * from scott.dept) d
  6  where d.deptno = e.deptno
  7    and e.job = 'SALESMAN'
  8  /

------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |              |     9 |   621 |     6  (34)| 00:00:01 |
|   1 |  NESTED LOOPS                   |              |     9 |   621 |     6  (34)| 00:00:01 |
|*  2 |   TABLE ACCESS FULL             | EMP          |     4 |   156 |     2   (0)| 00:00:01 |
|   3 |   VIEW                          |              |     1 |    30 |     4  (50)| 00:00:01 |
|   4 |    SORT UNIQUE                  |              |     2 |    40 |     4  (50)| 00:00:01 |
|   5 |     UNION ALL PUSHED PREDICATE  |              |       |       |            |          |
|   6 |      TABLE ACCESS BY INDEX ROWID| DEPT         |     1 |    20 |     1   (0)| 00:00:01 |
|*  7 |       INDEX UNIQUE SCAN         | SYS_C0093797 |     1 |       |     0   (0)| 00:00:01 |
|   8 |      TABLE ACCESS BY INDEX ROWID| DEPT         |     1 |    20 |     1   (0)| 00:00:01 |
|*  9 |       INDEX UNIQUE SCAN         | SYS_C0093797 |     1 |       |     0   (0)| 00:00:01 |
------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("E"."JOB"='SALESMAN')
   7 - access("DEPT"."DEPTNO"="E"."DEPTNO")
   9 - access("DEPT"."DEPTNO"="E"."DEPTNO")

Note
-----
   - Degree of Parallelism is 1 because of hint -- любопытное замечание, прямо противоположное используемому хинту PARALLEL(4)

— т.е. либо UNION ALL PUSHED PREDICATE, но НЕпараллельно; либо параллельно, но без PUSH_PRED (:

12.1.0.2.@SQL> select --+ PARALLEL(4) NO_PUSH_PRED(d)
  2  * from scott.emp e,
  3        (select * from scott.dept
  4         union
  5         select * from scott.dept) d
  6  where d.deptno = e.deptno
  7    and e.job = 'SALESMAN'
  8  /

----------------------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name     | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |          |     9 |   621 |     8  (25)| 00:00:01 |        |   |       |
|   1 |  PX COORDINATOR              |          |       |       |            |          |        |   |       |
|   2 |   PX SEND QC (RANDOM)        | :TQ10003 |     9 |   621 |     8  (25)| 00:00:01 |  Q1,03 | P->S | QC (RAND)  |
|*  3 |    HASH JOIN BUFFERED        |          |     9 |   621 |     8  (25)| 00:00:01 |  Q1,03 | PCWP |            |
|   4 |     PX RECEIVE               |          |     4 |   156 |     2   (0)| 00:00:01 |  Q1,03 | PCWP |            |
|   5 |      PX SEND HYBRID HASH     | :TQ10001 |     4 |   156 |     2   (0)| 00:00:01 |  Q1,01 | P->P | HYBRID HASH|
|   6 |       STATISTICS COLLECTOR   |          |       |       |            |          |  Q1,01 | PCWC |            |
|   7 |        PX BLOCK ITERATOR     |          |     4 |   156 |     2   (0)| 00:00:01 |  Q1,01 | PCWC |            |
|*  8 |         TABLE ACCESS FULL    | EMP      |     4 |   156 |     2   (0)| 00:00:01 |  Q1,01 | PCWP |            |
|   9 |     PX RECEIVE               |          |     8 |   240 |     6  (34)| 00:00:01 |  Q1,03 | PCWP |            |
|  10 |      PX SEND HYBRID HASH     | :TQ10002 |     8 |   240 |     6  (34)| 00:00:01 |  Q1,02 | P->P | HYBRID HASH|
|  11 |       VIEW                   |          |     8 |   240 |     6  (34)| 00:00:01 |  Q1,02 | PCWP |            |
|  12 |        SORT UNIQUE           |          |     8 |   160 |     6  (34)| 00:00:01 |  Q1,02 | PCWP |            |
|  13 |         PX RECEIVE           |          |       |       |            |          |  Q1,02 | PCWP |            |
|  14 |          PX SEND HASH        | :TQ10000 |       |       |            |          |  Q1,00 | P->P | HASH       |
|  15 |           UNION-ALL          |          |       |       |            |          |  Q1,00 | PCWP |            |
|  16 |            PX BLOCK ITERATOR |          |     4 |    80 |     2   (0)| 00:00:01 |  Q1,00 | PCWC |            |
|  17 |             TABLE ACCESS FULL| DEPT     |     4 |    80 |     2   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|  18 |            PX BLOCK ITERATOR |          |     4 |    80 |     2   (0)| 00:00:01 |  Q1,00 | PCWC |            |
|  19 |             TABLE ACCESS FULL| DEPT     |     4 |    80 |     2   (0)| 00:00:01 |  Q1,00 | PCWP |            |
----------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access("D"."DEPTNO"="E"."DEPTNO")
   8 - filter("E"."JOB"='SALESMAN')

Note
-----
   - Degree of Parallelism is 4 because of hint -- при отказе от PUSH_PRED, хинт PARALLEL(4) правильно воспринимается и отражается

Получить искомую комбинацию можно понизив OPTIMIZER_FEATURES_ENABLE до любого значения 11g:

12.1.0.2.@ SQL> select --+ PARALLEL(4) PUSH_PRED(d) OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
  2  * from scott.emp e,
  3        (select * from scott.dept
  4         union
  5         select * from scott.dept) d
  6  where d.deptno = e.deptno
  7    and e.job = 'SALESMAN'
  8  /

-------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name         | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
-------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |              |     9 |   621 |     6  (34)| 00:00:01 |     |         |            |
|   1 |  PX COORDINATOR                   |              |       |       |            |          |     |         |            |
|   2 |   PX SEND QC (RANDOM)             | :TQ10000     |     9 |   621 |     6  (34)| 00:00:01 |  Q1,00 | P->S | QC (RAND)  |
|   3 |    NESTED LOOPS                   |              |     9 |   621 |     6  (34)| 00:00:01 |  Q1,00 | PCWP |            |
|   4 |     PX BLOCK ITERATOR             |              |       |       |            |          |  Q1,00 | PCWC |            |
|*  5 |      TABLE ACCESS FULL            | EMP          |     4 |   156 |     2   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|   6 |     VIEW                          |              |     1 |    30 |     4  (50)| 00:00:01 |  Q1,00 | PCWP |            |
|   7 |      SORT UNIQUE                  |              |     2 |    40 |     4  (50)| 00:00:01 |  Q1,00 | PCWP |            |
|   8 |       UNION ALL PUSHED PREDICATE  |              |       |       |            |          |  Q1,00 | PCWP |            |
|   9 |        TABLE ACCESS BY INDEX ROWID| DEPT         |     1 |    20 |     1   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|* 10 |         INDEX UNIQUE SCAN         | SYS_C0093797 |     1 |       |     0   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|  11 |        TABLE ACCESS BY INDEX ROWID| DEPT         |     1 |    20 |     1   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|* 12 |         INDEX UNIQUE SCAN         | SYS_C0093797 |     1 |       |     0   (0)| 00:00:01 |  Q1,00 | PCWP |            |
-------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   5 - filter("E"."JOB"='SALESMAN')
  10 - access("DEPT"."DEPTNO"="E"."DEPTNO")
  12 - access("DEPT"."DEPTNO"="E"."DEPTNO")

Note
-----
   - Degree of Parallelism is 4 because of hint

и спец-ты поддержки формально подтвердили, что это безопасно)

II. Проблема фиксации параллельных планов

Выяснив, как получить желаемое, можно пробовать закрепить параллельный план для тестового запроса без подсказок:

12.1.0.2.@ SQL> select *
  2    from scott.emp e,
  3         (select *
  4            from scott.dept
  5          union
  6          select * from scott.dept) d
  7   where d.deptno = e.deptno
  8     and e.job = 'SALESMAN'
  9  /

4 rows selected.

12.1.0.2.@ SQL> @sql

SQL_ID             CHILD SQL_TEXT
------------- ---------- ------------------------------------------------------------
0p5661xfmm3xf          0 select *   from scott.emp e,        (select *           from
                          scott.dept         union         select * from scott.dept)
                         d  where d.deptno = e.deptno    and e.job = 'SALESMAN'

Целевой план получаем при выполнении хинтованного запроса:

12.1.0.2.@ SQL> select --+ PARALLEL(4) PUSH_PRED(d) OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
  2  * from scott.emp e,
  3        (select * from scott.dept
  4         union
  5         select * from scott.dept) d
  6  where d.deptno = e.deptno
  7    and e.job = 'SALESMAN'
  8  /

4 rows selected.

12.1.0.2.SYS@db2g/OEBS2 SQL> @xplan
Enter value for 1:
Enter value for 2:
Enter value for 3: +outline -predicate

PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  aq7hj7ms0d2g8, child number 0
-------------------------------------

Plan hash value: 1527564050

-------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name         | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
-------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |              |       |       |     6 (100)|          |     |         |            |
|   1 |  PX COORDINATOR                   |              |       |       |            |          |     |         |            |
|   2 |   PX SEND QC (RANDOM)             | :TQ10000     |     9 |   621 |     6  (34)| 00:00:01 |  Q1,00 | P->S | QC (RAND)  |
|   3 |    NESTED LOOPS                   |              |     9 |   621 |     6  (34)| 00:00:01 |  Q1,00 | PCWP |            |
|   4 |     PX BLOCK ITERATOR             |              |       |       |            |          |  Q1,00 | PCWC |            |
|*  5 |      TABLE ACCESS FULL            | EMP          |     4 |   156 |     2   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|   6 |     VIEW                          |              |     1 |    30 |     4  (50)| 00:00:01 |  Q1,00 | PCWP |            |
|   7 |      SORT UNIQUE                  |              |     2 |    40 |     4  (50)| 00:00:01 |  Q1,00 | PCWP |            |
|   8 |       UNION ALL PUSHED PREDICATE  |              |       |       |            |          |  Q1,00 | PCWP |            |
|   9 |        TABLE ACCESS BY INDEX ROWID| DEPT         |     1 |    20 |     1   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|* 10 |         INDEX UNIQUE SCAN         | SYS_C0093797 |     1 |       |     0   (0)|          |  Q1,00 | PCWP |            |
|  11 |        TABLE ACCESS BY INDEX ROWID| DEPT         |     1 |    20 |     1   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|* 12 |         INDEX UNIQUE SCAN         | SYS_C0093797 |     1 |       |     0   (0)|          |  Q1,00 | PCWP |            |
-------------------------------------------------------------------------------------------------------------------------------

Outline Data
-------------

  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
      DB_VERSION('12.1.0.2')
      OPT_PARAM('_fix_control' '17376322:0')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$639F1A6F")
      OUTLINE_LEAF(@"SEL$B01C6807")
      OUTLINE_LEAF(@"SET$5715CE2E")
      PUSH_PRED(@"SEL$1" "D"@"SEL$1" 1)
      OUTLINE_LEAF(@"SEL$1")
      OUTLINE(@"SEL$2")
      OUTLINE(@"SEL$3")
      OUTLINE(@"SET$1")
      OUTLINE(@"SEL$1")
      FULL(@"SEL$1" "E"@"SEL$1")
      NO_ACCESS(@"SEL$1" "D"@"SEL$1")
      LEADING(@"SEL$1" "E"@"SEL$1" "D"@"SEL$1")
      USE_NL(@"SEL$1" "D"@"SEL$1")
      PQ_DISTRIBUTE(@"SEL$1" "D"@"SEL$1" NONE BROADCAST)
      INDEX_RS_ASC(@"SEL$B01C6807" "DEPT"@"SEL$3" ("DEPT"."DEPTNO"))
      INDEX_RS_ASC(@"SEL$639F1A6F" "DEPT"@"SEL$2" ("DEPT"."DEPTNO"))
      END_OUTLINE_DATA
  */

Note
-----
   - Degree of Parallelism is 4 because of hint

и пробуем создать SQL Profile для запроса 0p5661xfmm3xf:

12.1.0.2.@ SQL> @sql_profile_from_sql2 aq7hj7ms0d2g8 1527564050 0p5661xfmm3xf "0p5661xfmm3xf_1527564050" "0p5661xfmm3xf_1527564050"

PL/SQL procedure successfully completed.

HINT
--------------------------------------------------------------------------------------------------------------------------------------------------------------
ALL_ROWS
DB_VERSION('12.1.0.2')
FULL(@"SEL$1" "E"@"SEL$1")
IGNORE_OPTIM_EMBEDDED_HINTS
INDEX_RS_ASC(@"SEL$639F1A6F" "DEPT"@"SEL$2" ("DEPT"."DEPTNO"))
INDEX_RS_ASC(@"SEL$B01C6807" "DEPT"@"SEL$3" ("DEPT"."DEPTNO"))
LEADING(@"SEL$1" "E"@"SEL$1" "D"@"SEL$1")
NO_ACCESS(@"SEL$1" "D"@"SEL$1")
OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
OPT_PARAM('_fix_control' '17376322:0')
OUTLINE(@"SEL$1")
OUTLINE(@"SEL$2")
OUTLINE(@"SEL$3")
OUTLINE(@"SET$1")
OUTLINE_LEAF(@"SEL$1")
OUTLINE_LEAF(@"SEL$639F1A6F")
OUTLINE_LEAF(@"SEL$B01C6807")
OUTLINE_LEAF(@"SET$5715CE2E")
PQ_DISTRIBUTE(@"SEL$1" "D"@"SEL$1" NONE BROADCAST) -- *
PUSH_PRED(@"SEL$1" "D"@"SEL$1" 1)
USE_NL(@"SEL$1" "D"@"SEL$1")

21 rows selected.

Созданный SQL Profile к запросу успешно применяется, однако воспроизводит только последовательность операций (в частности, UNION ALL PUSHED PREDICATE), но не параллельное выполнение, несмотря на содержащийся в Profile предполагающий хинт PQ_DISTRIBUTE(*):

12.1.0.2.@ SQL> select *
  2    from scott.emp e,
  3         (select *
  4            from scott.dept
  5          union
  6          select * from scott.dept) d
  7   where d.deptno = e.deptno
  8     and e.job = 'SALESMAN'
  9  /

4 rows selected.

12.1.0.2.@ SQL> @xplan "" "" "+outline"

Plan hash value: 4246912226

------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |              |       |       |    23 (100)|          |
|   1 |  NESTED LOOPS                   |              |     9 |   621 |    23  (35)| 00:00:01 |
|*  2 |   TABLE ACCESS FULL             | EMP          |     4 |   156 |     7   (0)| 00:00:01 |
|   3 |   VIEW                          |              |     1 |    30 |     4  (50)| 00:00:01 |
|   4 |    SORT UNIQUE                  |              |     2 |    40 |     4  (50)| 00:00:01 |
|   5 |     UNION ALL PUSHED PREDICATE  |              |       |       |            |          |
|   6 |      TABLE ACCESS BY INDEX ROWID| DEPT         |     1 |    20 |     1   (0)| 00:00:01 |
|*  7 |       INDEX UNIQUE SCAN         | SYS_C0093797 |     1 |       |     0   (0)|          |
|   8 |      TABLE ACCESS BY INDEX ROWID| DEPT         |     1 |    20 |     1   (0)| 00:00:01 |
|*  9 |       INDEX UNIQUE SCAN         | SYS_C0093797 |     1 |       |     0   (0)|          |
------------------------------------------------------------------------------------------------

Outline Data
-------------

  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
      DB_VERSION('12.1.0.2')
      OPT_PARAM('_fix_control' '17376322:0')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$639F1A6F")
      OUTLINE_LEAF(@"SEL$B01C6807")
      OUTLINE_LEAF(@"SET$5715CE2E")
      PUSH_PRED(@"SEL$1" "D"@"SEL$1" 1)
      OUTLINE_LEAF(@"SEL$1")
      OUTLINE(@"SEL$2")
      OUTLINE(@"SEL$3")
      OUTLINE(@"SET$1")
      OUTLINE(@"SEL$1")
      FULL(@"SEL$1" "E"@"SEL$1")
      NO_ACCESS(@"SEL$1" "D"@"SEL$1")
      LEADING(@"SEL$1" "E"@"SEL$1" "D"@"SEL$1")
      USE_NL(@"SEL$1" "D"@"SEL$1")
      INDEX_RS_ASC(@"SEL$B01C6807" "DEPT"@"SEL$3" ("DEPT"."DEPTNO"))
      INDEX_RS_ASC(@"SEL$639F1A6F" "DEPT"@"SEL$2" ("DEPT"."DEPTNO"))
      END_OUTLINE_DATA
  */

Note
-----
   - SQL profile 0p5661xfmm3xf_1527564050 used for this statement

Для фиксации параллельности выполнения плана придётся либо добавить соотв.подсказку в Profile, либо создать дополнительно SQL Patch для этого запроса:

12.1.0.2.@ SQL> @sqlpatch+
Enter SQL_ID (required):0p5661xfmm3xf
Enter SQL_PATCH_TEXT (required):shared(4)
Enter SQL_PATCH_NAME (required):0p5661xfmm3xf_shared

PL/SQL procedure successfully completed.

SQL_ID        NAME                  CATEGORY  CREATED               STATUS   FMA
------------- --------------------- --------- --------------------- -------- ---
0p5661xfmm3xf 0p5661xfmm3xf_shared  DEFAULT   09.09.2016 12:09:59   ENABLED  NO

SQL_PATCH_HINTS
-------------------------
shared(4)

— что действительно позволяет воспроизвести/зафиксировать параллельный план 1527564050:

12.1.0.2.@ SQL> select *
  2    from scott.emp e,
  3         (select *
  4            from scott.dept
  5          union
  6          select * from scott.dept) d
  7   where d.deptno = e.deptno
  8     and e.job = 'SALESMAN'
  9  /

4 rows selected.

12.1.0.2.@ SQL> @xplan "" "" "+outline -predicate"

Plan hash value: 1527564050

-------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name         | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
-------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |              |       |       |     6 (100)|          |     |         |            |
|   1 |  PX COORDINATOR                   |              |       |       |            |          |     |         |            |
|   2 |   PX SEND QC (RANDOM)             | :TQ10000     |     9 |   621 |     6  (34)| 00:00:01 |  Q1,00 | P->S | QC (RAND)  |
|   3 |    NESTED LOOPS                   |              |     9 |   621 |     6  (34)| 00:00:01 |  Q1,00 | PCWP |            |
|   4 |     PX BLOCK ITERATOR             |              |       |       |            |          |  Q1,00 | PCWC |            |
|*  5 |      TABLE ACCESS FULL            | EMP          |     4 |   156 |     2   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|   6 |     VIEW                          |              |     1 |    30 |     4  (50)| 00:00:01 |  Q1,00 | PCWP |            |
|   7 |      SORT UNIQUE                  |              |     2 |    40 |     4  (50)| 00:00:01 |  Q1,00 | PCWP |            |
|   8 |       UNION ALL PUSHED PREDICATE  |              |       |       |            |          |  Q1,00 | PCWP |            |
|   9 |        TABLE ACCESS BY INDEX ROWID| DEPT         |     1 |    20 |     1   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|* 10 |         INDEX UNIQUE SCAN         | SYS_C0093797 |     1 |       |     0   (0)|          |  Q1,00 | PCWP |            |
|  11 |        TABLE ACCESS BY INDEX ROWID| DEPT         |     1 |    20 |     1   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|* 12 |         INDEX UNIQUE SCAN         | SYS_C0093797 |     1 |       |     0   (0)|          |  Q1,00 | PCWP |            |
-------------------------------------------------------------------------------------------------------------------------------

Outline Data
-------------

  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
      DB_VERSION('12.1.0.2')
      OPT_PARAM('_fix_control' '17376322:0')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$639F1A6F")
      OUTLINE_LEAF(@"SEL$B01C6807")
      OUTLINE_LEAF(@"SET$5715CE2E")
      PUSH_PRED(@"SEL$1" "D"@"SEL$1" 1)
      OUTLINE_LEAF(@"SEL$1")
      OUTLINE(@"SEL$2")
      OUTLINE(@"SEL$3")
      OUTLINE(@"SET$1")
      OUTLINE(@"SEL$1")
      FULL(@"SEL$1" "E"@"SEL$1")
      NO_ACCESS(@"SEL$1" "D"@"SEL$1")
      LEADING(@"SEL$1" "E"@"SEL$1" "D"@"SEL$1")
      USE_NL(@"SEL$1" "D"@"SEL$1")
      PQ_DISTRIBUTE(@"SEL$1" "D"@"SEL$1" NONE BROADCAST)
      INDEX_RS_ASC(@"SEL$B01C6807" "DEPT"@"SEL$3" ("DEPT"."DEPTNO"))
      INDEX_RS_ASC(@"SEL$639F1A6F" "DEPT"@"SEL$2" ("DEPT"."DEPTNO"))
      END_OUTLINE_DATA
  */

Note
-----
   - Degree of Parallelism is 4 because of hint
   - SQL profile 0p5661xfmm3xf_1527564050 used for this statement
   - SQL patch "0p5661xfmm3xf_shared" used for this statement

Получается, что только данных из Outline (набора хинтов) недостаточно для сохранения/воспроизведения параллельного плана выполнения, по крайней мере, если использовать [для фиксации плана] SQL Profile

Аналогично не получается воспроизвести параллельный план с помощью SPM Baseline, предварительно удалив SQL profile & SQL patch:

12.1.0.2.@ SQL> exec dbms_sqltune.drop_sql_profile(name => '0p5661xfmm3xf_1527564050', ignore => TRUE)

PL/SQL procedure successfully completed.

12.1.0.2.@ SQL> @sqlpatch- "0p5661xfmm3xf_shared" 0p5661xfmm3xf

PL/SQL procedure successfully completed.

SPM Elements (SQL Profile, or SQL Plan Baseline, or SQL Patch) List for SQL_ID = 0p5661xfmm3xf

no rows selected

и создав Baseline из имеющегося в Shared Pool плана:

12.1.0.2.@ SQL> @bl_create 0p5661xfmm3xf 1527564050 "0p5661xfmm3xf_1527564050_p4"

Baseline SQL_9161dec47579acb8 SQL_PLAN_92sfysjurmb5s3d1c42b0 was [re]created
for SQL_ID=0p5661xfmm3xf, SQL_PLAN_HASH=1527564050

12.1.0.2.@ SQL> @bl12_hints SQL_PLAN_92sfysjurmb5s3d1c42b0

OUTLINE_HINTS
-------------------------------------------------------------- получающийся Baseline кроме Outline хинтов (составлявшим так же и SQL profile)
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
DB_VERSION('12.1.0.2')
OPT_PARAM('_fix_control' '17376322:0')
ALL_ROWS
OUTLINE_LEAF(@"SEL$639F1A6F")
OUTLINE_LEAF(@"SEL$B01C6807")
OUTLINE_LEAF(@"SET$5715CE2E")
PUSH_PRED(@"SEL$1" "D"@"SEL$1" 1)
OUTLINE_LEAF(@"SEL$1")
OUTLINE(@"SEL$2")
OUTLINE(@"SEL$3")
OUTLINE(@"SET$1")
OUTLINE(@"SEL$1")
FULL(@"SEL$1" "E"@"SEL$1")
NO_ACCESS(@"SEL$1" "D"@"SEL$1")
LEADING(@"SEL$1" "E"@"SEL$1" "D"@"SEL$1")
USE_NL(@"SEL$1" "D"@"SEL$1")
PQ_DISTRIBUTE(@"SEL$1" "D"@"SEL$1" NONE BROADCAST)
INDEX_RS_ASC(@"SEL$B01C6807" "DEPT"@"SEL$3" ("DEPT"."DEPTNO"))
INDEX_RS_ASC(@"SEL$639F1A6F" "DEPT"@"SEL$2" ("DEPT"."DEPTNO"))

Notes
-------------------------------------------------------------- включает секцию Notes с точным указанием целевого DOP, в частности (**)
   sql_profile:     "0p5661xfmm3xf_1527564050"
   sql_patch:       "0p5661xfmm3xf_shared"
   baseline:
   outline:
   dyn_sampling:
   dop:             4                                         -- **
   dop_reason:      hint                                      -- **
   card_feedback:
   perf_feedback:
   adaptive_plan:
   spd_used:
   spd_valid:
   gtt_sess_stat:
   db_version:      12.1.0.2
   plan_hash_full:  1025262256
   plan_hash:       1527564050
   plan_hash_2:     1025262256

Воспроизвести план не получается по причине невозможности воспроизведения/применения Baseline к запросу:

12.1.0.2.@ SQL> select *
  2    from scott.emp e,
  3         (select *
  4            from scott.dept
  5          union
  6          select * from scott.dept) d
  7   where d.deptno = e.deptno
  8     and e.job = 'SALESMAN'
  9  /

4 rows selected.

12.1.0.2.@ SQL> @xplan "" "" "+outline -predicate"

Plan hash value: 3794292649

------------------------------------------------------------------------------
| Id  | Operation             | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |      |       |       |    13 (100)|          |
|*  1 |  HASH JOIN            |      |     9 |   621 |    13  (16)| 00:00:01 |
|*  2 |   TABLE ACCESS FULL   | EMP  |     4 |   156 |     7   (0)| 00:00:01 |
|   3 |   VIEW                |      |     8 |   240 |     6  (34)| 00:00:01 |
|   4 |    SORT UNIQUE        |      |     8 |   160 |     6  (34)| 00:00:01 |
|   5 |     UNION-ALL         |      |       |       |            |          |
|   6 |      TABLE ACCESS FULL| DEPT |     4 |    80 |     2   (0)| 00:00:01 |
|   7 |      TABLE ACCESS FULL| DEPT |     4 |    80 |     2   (0)| 00:00:01 |
------------------------------------------------------------------------------

Outline Data
-------------

  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('12.1.0.2')
      DB_VERSION('12.1.0.2')
      OPT_PARAM('_fix_control' '17376322:0')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$2")
      OUTLINE_LEAF(@"SEL$3")
      OUTLINE_LEAF(@"SET$1")
      OUTLINE_LEAF(@"SEL$1")
      FULL(@"SEL$1" "E"@"SEL$1")
      NO_ACCESS(@"SEL$1" "D"@"SEL$1")
      LEADING(@"SEL$1" "E"@"SEL$1" "D"@"SEL$1")
      USE_HASH(@"SEL$1" "D"@"SEL$1")
      FULL(@"SEL$3" "DEPT"@"SEL$3")
      FULL(@"SEL$2" "DEPT"@"SEL$2")
      END_OUTLINE_DATA
  */

— по причине описанной радикальной хрупкости Baseline («всё или ничего!»), далее — из 10053 трейса:

**************************
Automatic degree of parallelism (AUTODOP)
**************************
Automatic degree of parallelism is disabled: Parameter.
kkopqSetForceParallelProperties: Hint:no
Query: compute:yes forced:no forceDop:0
kkopqSetDopReason: Reason why we chose this DOP is: table property.
table property forces parallelism

Global Manual DOP: 1 - Rounded?: no -- нет оснований для увеличения DOP, т.е. собственно информация из Baseline Notes - не является достаточным основанием
...
SPM: failed to reproduce the plan using the following info: -- как следствие невозможно воспроизвести целевой параллельный план с OFE = 11.2.0.4 (***)
  parse_schema name        : SYS
  plan_baseline signature  : 10475899143606348984
  plan_baseline plan_id    : 1025262256
  plan_baseline hintset    :
    hint num  1 len 27 text: IGNORE_OPTIM_EMBEDDED_HINTS
    hint num  2 len 37 text: OPTIMIZER_FEATURES_ENABLE('11.2.0.4')              -- ***
    hint num  3 len 22 text: DB_VERSION('12.1.0.2')
...
    hint num 19 len 50 text: PQ_DISTRIBUTE(@"SEL$1" "D"@"SEL$1" NONE BROADCAST) -- ***
...
SPM: generated non-matching plan: -- далее генерация плана происходит привычным порядком по правилам CBO

Кстати, после неудачной попытки применения статус Baseline упорно остаётся REPRODUCED = YES — верь после этого людям:)

SQL> @spm_check4sql_id 0p5661xfmm3xf
 
SIGNATURE             SPM_TYPE          SQL_HANDLE            PATCH_NAME                     ORIGIN      VERSION     CREATED             LAST_MODIFIED       LAST_EXECUTED ENABLED ACCEPTED FIXED REPRODUCED AUTOPURGE
--------------------- ----------------- --------------------- ------------------------------ ----------- ----------- ------------------- ------------------- ------------- ------- -------- ----- ---------- ---------
 10475899143606348984 SQL Plan Baseline SQL_9161dec47579acb8  SQL_PLAN_92sfysjurmb5s3d1c42b0 MANUAL-LOAD 12.1.0.2.0  09.09.2016 12:22:13 09.09.2016 12:22:20               YES     YES      YES   YES        NO

В итоге можно сделать вывод, что закрепить параллельный план запроса только с помощью SPM инструментов, фиксирующих Outline запроса (SQL Profile или Baseline) не получится — в обоих случаях требуется доп.стимулирование DOP с помощью подсказки (через текстовый хинт, либо через добавление подсказки в SQL Patch/Profile) или изменение параллельных свойств таблиц/индексов

4 комментария »

  1. Игорь, а в профиле этот хинт не работал? Только через SQL Patch удалось параллельность ему выставить?

    комментарий от leborchuk — 15.09.2016 @ 09:55 | Ответить

    • да, конечно, Лёня, в профиле parallel тоже будет работать (если добавить), просто профиль мне было удобно делать из Outline существующего плана, кот. не содержит ни parallel, ни shared хинтов

      комментарий от Игорь Усольцев — 15.09.2016 @ 11:19 | Ответить

  2. Спасибо за подробную статью.

    Небольшое дополнение по первой части (все касается 12ой версии оптимизатора):
    выключив индексный доступ:

    alter index scott.pk_dept invisible;

    и упростив жизнь запросу заменив на union all , получаем вполне себе параллельный доступ:

    select --+ PARALLEL(4) PUSH_PRED(d)
      * from scott.emp e,
            (select * from scott.dept
             union all
             select * from scott.dept) d
      where d.deptno = e.deptno
        and e.job = 'SALESMAN'
    ;
    
    -------------------------------------------------------------------------------------------------------------------------
    | Id  | Operation			| Name	   | Rows  | Bytes | Cost (%CPU)| Time	   |	TQ  |IN-OUT| PQ Distrib |
    -------------------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT		|	   |	 6 |   348 |	 7   (0)| 00:00:01 |	    |	   |		|
    |   1 |  PX COORDINATOR 		|	   |	   |	   |		|	   |	    |	   |		|
    |   2 |   PX SEND QC (RANDOM)		| :TQ10000 |	 6 |   348 |	 7   (0)| 00:00:01 |  Q1,00 | P->S | QC (RAND)	|
    |   3 |    NESTED LOOPS 		|	   |	 6 |   348 |	 7   (0)| 00:00:01 |  Q1,00 | PCWP |		|
    |   4 |     PX BLOCK ITERATOR		|	   |	   |	   |		|	   |  Q1,00 | PCWC |		|
    |*  5 |      TABLE ACCESS FULL		| EMP	   |	 3 |   114 |	 2   (0)| 00:00:01 |  Q1,00 | PCWP |		|
    |   6 |     VIEW			|	   |	 1 |	20 |	 6   (0)| 00:00:01 |  Q1,00 | PCWP |		|
    |   7 |      UNION ALL PUSHED PREDICATE |	   |	   |	   |		|	   |  Q1,00 | PCWP |		|
    |*  8 |       TABLE ACCESS FULL 	| DEPT	   |	 1 |	20 |	 3   (0)| 00:00:01 |  Q1,00 | PCWP |		|
    |*  9 |       TABLE ACCESS FULL 	| DEPT	   |	 1 |	20 |	 3   (0)| 00:00:01 |  Q1,00 | PCWP |		|
    -------------------------------------------------------------------------------------------------------------------------

    При этом, вернув обратно union:

    select --+ PARALLEL(4) PUSH_PRED(d)
      * from scott.emp e,
            (select * from scott.dept
             union
             select * from scott.dept) d
      where d.deptno = e.deptno
        and e.job = 'SALESMAN'
    ;
    
    ---------------------------------------------------------------------------------------
    | Id  | Operation		       | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT	       |      |     7 |   476 |     9  (23)| 00:00:01 |
    |   1 |  NESTED LOOPS		       |      |     7 |   476 |     9  (23)| 00:00:01 |
    |*  2 |   TABLE ACCESS FULL	       | EMP  |     3 |   114 |     2	(0)| 00:00:01 |
    |   3 |   VIEW			       |      |     1 |    30 |     8  (25)| 00:00:01 |
    |   4 |    SORT UNIQUE		       |      |     2 |    40 |     8  (25)| 00:00:01 |
    |   5 |     UNION ALL PUSHED PREDICATE |      |       |       | 	   |	      |
    |*  6 |      TABLE ACCESS FULL	       | DEPT |     1 |    20 |     3	(0)| 00:00:01 |
    |*  7 |      TABLE ACCESS FULL	       | DEPT |     1 |    20 |     3	(0)| 00:00:01 |
    ---------------------------------------------------------------------------------------

    Параллельно становится выполняться уже сложнее, но можно:

    select --+ PARALLEL(e 4) PUSH_PRED(d)
      * from scott.emp e,
            (select * from scott.dept
             union
             select * from scott.dept) d
      where d.deptno = e.deptno
        and e.job = 'SALESMAN'
    ;
    
    --------------------------------------------------------------------------------------------------------------------------
    | Id  | Operation			 | Name     | Rows  | Bytes | Cost (%CPU)| Time     |	 TQ  |IN-OUT| PQ Distrib |
    --------------------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT		 |	    |	  7 |	476 |	  9  (23)| 00:00:01 |	     |	    |		 |
    |   1 |  PX COORDINATOR 		 |	    |	    |	    |		 |	    |	     |	    |		 |
    |   2 |   PX SEND QC (RANDOM)		 | :TQ10000 |	  7 |	476 |	  9  (23)| 00:00:01 |  Q1,00 | P->S | QC (RAND)  |
    |   3 |    NESTED LOOPS 		 |	    |	  7 |	476 |	  9  (23)| 00:00:01 |  Q1,00 | PCWP |		 |
    |   4 |     PX BLOCK ITERATOR		 |	    |	    |	    |		 |	    |  Q1,00 | PCWC |		 |
    |*  5 |      TABLE ACCESS FULL		 | EMP	    |	  3 |	114 |	  2   (0)| 00:00:01 |  Q1,00 | PCWP |		 |
    |   6 |     VIEW			 |	    |	  1 |	 30 |	  8  (25)| 00:00:01 |  Q1,00 | PCWP |		 |
    |   7 |      SORT UNIQUE		 |	    |	  2 |	 40 |	  8  (25)| 00:00:01 |  Q1,00 | PCWP |		 |
    |   8 |       UNION ALL PUSHED PREDICATE |	    |	    |	    |		 |	    |  Q1,00 | PCWP |		 |
    |*  9 |        TABLE ACCESS FULL	 | DEPT     |	  1 |	 20 |	  3   (0)| 00:00:01 |  Q1,00 | PCWP |		 |
    |* 10 |        TABLE ACCESS FULL	 | DEPT     |	  1 |	 20 |	  3   (0)| 00:00:01 |  Q1,00 | PCWP |		 |
    --------------------------------------------------------------------------------------------------------------------------

    Это же работает и при наличии индекса:

    alter index scott.pk_dept visible;
    
    select --+ PARALLEL(e 4) PUSH_PRED(d)
      * from scott.emp e,
            (select * from scott.dept
             union
             select * from scott.dept) d
      where d.deptno = e.deptno
        and e.job = 'SALESMAN'
    ;
    
    ---------------------------------------------------------------------------------------------------------------------------
    | Id  | Operation			  | Name     | Rows  | Bytes | Cost (%CPU)| Time     |	  TQ  |IN-OUT| PQ Distrib |
    ---------------------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT		  |	     |	   7 |	 476 |	   5  (20)| 00:00:01 |	      |      |		  |
    |   1 |  PX COORDINATOR 		  |	     |	     |	     |		  |	     |	      |      |		  |
    |   2 |   PX SEND QC (RANDOM)		  | :TQ10000 |	   7 |	 476 |	   5  (20)| 00:00:01 |	Q1,00 | P->S | QC (RAND)  |
    |   3 |    NESTED LOOPS 		  |	     |	   7 |	 476 |	   5  (20)| 00:00:01 |	Q1,00 | PCWP |		  |
    |   4 |     PX BLOCK ITERATOR		  |	     |	     |	     |		  |	     |	Q1,00 | PCWC |		  |
    |*  5 |      TABLE ACCESS FULL		  | EMP      |	   3 |	 114 |	   2   (0)| 00:00:01 |	Q1,00 | PCWP |		  |
    |   6 |     VIEW			  |	     |	   1 |	  30 |	   4  (50)| 00:00:01 |	Q1,00 | PCWP |		  |
    |   7 |      SORT UNIQUE		  |	     |	   2 |	  40 |	   4  (50)| 00:00:01 |	Q1,00 | PCWP |		  |
    |   8 |       UNION ALL PUSHED PREDICATE  |	     |	     |	     |		  |	     |	Q1,00 | PCWP |		  |
    |   9 |        TABLE ACCESS BY INDEX ROWID| DEPT     |	   1 |	  20 |	   1   (0)| 00:00:01 |	Q1,00 | PCWP |		  |
    |* 10 | 	INDEX UNIQUE SCAN	  | PK_DEPT  |	   1 |	     |	   0   (0)| 00:00:01 |	Q1,00 | PCWP |		  |
    |  11 |        TABLE ACCESS BY INDEX ROWID| DEPT     |	   1 |	  20 |	   1   (0)| 00:00:01 |	Q1,00 | PCWP |		  |
    |* 12 | 	INDEX UNIQUE SCAN	  | PK_DEPT  |	   1 |	     |	   0   (0)| 00:00:01 |	Q1,00 | PCWP |		  |
    ---------------------------------------------------------------------------------------------------------------------------

    К чему это я все: PUSHED PREDICATE не является единственной и основной проблемой подобных сложностей, ну и решать проблему можно несколько иначе (хотя в более комплексных случаях это будет сделать сложнее).

    комментарий от rbikblog — 15.09.2016 @ 09:59 | Ответить

    • Спасибо, Руслан, отлично!

      Интересно в последнем примере:

      PLAN_TABLE_OUTPUT
      -------------------------------------------------------------------------------------------------------------------------------
      SQL_ID  39cu2rm8jpp6t, child number 0
      -------------------------------------
      select --+ PARALLEL(e 4) PUSH_PRED(d)   * from scott.emp e,
      (select * from scott.dept          union          select * from
      scott.dept) d   where d.deptno = e.deptno     and e.job = 'SALESMAN'
      
      Plan hash value: 1527564050
      
      -------------------------------------------------------------------------------------------------------------------------------
      | Id  | Operation                         | Name         | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
      -------------------------------------------------------------------------------------------------------------------------------
      |   0 | SELECT STATEMENT                  |              |       |       |     6 (100)|          |     |         |            |
      |   1 |  PX COORDINATOR                   |              |       |       |            |          |     |         |            |
      |   2 |   PX SEND QC (RANDOM)             | :TQ10000     |     9 |   621 |     6  (34)| 00:00:01 |  Q1,00 | P->S | QC (RAND)  |
      |   3 |    NESTED LOOPS                   |              |     9 |   621 |     6  (34)| 00:00:01 |  Q1,00 | PCWP |            |
      |   4 |     PX BLOCK ITERATOR             |              |       |       |            |          |  Q1,00 | PCWC |            |
      |*  5 |      TABLE ACCESS FULL            | EMP          |     4 |   156 |     2   (0)| 00:00:01 |  Q1,00 | PCWP |            |
      |   6 |     VIEW                          |              |     1 |    30 |     4  (50)| 00:00:01 |  Q1,00 | PCWP |            |
      |   7 |      SORT UNIQUE                  |              |     2 |    40 |     4  (50)| 00:00:01 |  Q1,00 | PCWP |            |
      |   8 |       UNION ALL PUSHED PREDICATE  |              |       |       |            |          |  Q1,00 | PCWP |            |
      |   9 |        TABLE ACCESS BY INDEX ROWID| DEPT         |     1 |    20 |     1   (0)| 00:00:01 |  Q1,00 | PCWP |            |
      |* 10 |         INDEX UNIQUE SCAN         | SYS_C0093797 |     1 |       |     0   (0)|          |  Q1,00 | PCWP |            |
      |  11 |        TABLE ACCESS BY INDEX ROWID| DEPT         |     1 |    20 |     1   (0)| 00:00:01 |  Q1,00 | PCWP |            |
      |* 12 |         INDEX UNIQUE SCAN         | SYS_C0093797 |     1 |       |     0   (0)|          |  Q1,00 | PCWP |            |
      -------------------------------------------------------------------------------------------------------------------------------
      
      Note
      -----
         - Degree of Parallelism is 4 because of table property

      — как следует из Note, параллельное выполнение явилось следствием table property, т.о. хинт PARALLEL(e 4) с указанием объекта бд временно меняет свойства таблицы, трейс подтверждает:

      Automatic degree of parallelism (AUTODOP)
      **************************
      Automatic degree of parallelism is disabled: Parameter.
      kkopqSetForceParallelProperties: Hint:no
      Query: compute:yes forced:no forceDop:0
      kkopqSetDopReason: Reason why we chose this DOP is: table property. -- здесь
      table property forces parallelism
      
      Global Manual DOP: 4 - Rounded?: no

      комментарий от Игорь Усольцев — 15.09.2016 @ 11:49 | Ответить


RSS feed for comments on this post. TrackBack URI

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

Создайте бесплатный сайт или блог на WordPress.com.

%d такие блоггеры, как: