Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Распараллеливание запросов с временными таблицами в Oracle11  [new]
ВладГ
Member

Откуда:
Сообщений: 2
При установке PARALLEL_DEGREE_POLICY = AUTO длинные запросы с участием временных (GLOBAL TEMPORARY) таблиц распараллеливаются Oracle'ом автоматически, но поскольку временная таблица является сессионно- зависимой, а на каждый распараллеленный кусок создается своя сессия (проверено), в которых содержимое временной таблицы пусто, поэтому запрос выполняется неверно.
Существует ли какой-то способ борьбы с этим, кроме PARALLEL_DEGREE_POLICY = MANUAL и указания распараллеливания, где скажу?
10 янв 11, 09:46    [10047474]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
wurdu
Member

Откуда: Владивосток
Сообщений: 4441
Если описанное поведение имеет место - это баг. Но на 11.2.0.1 я воспроизвести не могу - параллельные процессы видят таблицу. Так что нужен тест кейс, чтобы можно было воспроизвести.
10 янв 11, 10:52    [10047602]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
ВладГ
Member

Откуда:
Сообщений: 2
Большое спасибо за ответ. При ближайшем рассмотрении оказалось, что временная таблица использовалась в функции, использованной во фразе WHERE, так что Oracle имел полное право про нее не знать. Эксперименты со смесью временных и постоянных таблиц показали, что Oracle не распараллеливает такие запросы, даже при принудительном Hint'е.
10 янв 11, 11:47    [10047768]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
wurdu
Member

Откуда: Владивосток
Сообщений: 4441
ВладГ
... Эксперименты со смесью временных и постоянных таблиц показали, что Oracle не распараллеливает такие запросы, даже при принудительном Hint'е.
Мне не известны такие ограничения и на практике легко распараллелить запрос с участием временной и обычной таблицы.
10 янв 11, 12:03    [10047828]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
wurdu
Member

Откуда: Владивосток
Сообщений: 4441
ВладГ
Большое спасибо за ответ. При ближайшем рассмотрении оказалось, что временная таблица использовалась в функции, использованной во фразе WHERE, так что Oracle имел полное право про нее не знать.
Я воспроизвел эту проблему на 11.2.0.1 и считаю это багом. Типичный wrong result.
10 янв 11, 12:41    [10047967]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
wurdu,

похоже проблема в этом
VLDB and Partitioning Guide
Functions in Parallel DML and DDL Statements

In a parallel DML or DDL statement, as in a parallel query, a user-written function
may be executed in parallel in any of the following cases:

■ If it has been declared with the PARALLEL_ENABLE keyword

■ If it is declared in a package or type and has a PRAGMA RESTRICT_REFERENCES clause that indicates all of RNDS, WNDS, RNPS, and WNPS

■ If it is declared with the CREATE FUNCTION statement and the system can analyze the body of the PL/SQL code and determine that the code neither reads nor writes to the database or reads or modifies package variables

For a parallel DML statement, any function call that cannot be executed in parallel causes the entire DML statement to be executed serially. For an INSERT ... SELECT or CREATE TABLE ... AS SELECT statement, function calls in the query portion are parallelized according to the parallel query rules in the previous paragraph. The query may be parallelized even if the remainder of the statement must execute serially, or vice versa.

Стоит поместить фынкцию в пакет, она начинает работать нормально в плане появляется PX COORDINATOR FORCED SERIAL
10 янв 11, 13:54    [10048295]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
wurdu
Мне не известны такие ограничения и на практике легко распараллелить запрос с участием временной и обычной таблицы.

А ограничения есть. Например Doc ID 457040.1, связанный с тем что NL+parallel не умеет нормально работать с GTT.
10 янв 11, 14:46    [10048547]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
wurdu
Member

Откуда: Владивосток
Сообщений: 4441
_Nikotin
wurdu,

похоже проблема в этом
VLDB and Partitioning Guide
Functions in Parallel DML and DDL Statements

In a parallel DML or DDL statement, as in a parallel query, a user-written function
may be executed in parallel in any of the following cases:

■ If it has been declared with the PARALLEL_ENABLE keyword

■ If it is declared in a package or type and has a PRAGMA RESTRICT_REFERENCES clause that indicates all of RNDS, WNDS, RNPS, and WNPS

■ If it is declared with the CREATE FUNCTION statement and the system can analyze the body of the PL/SQL code and determine that the code neither reads nor writes to the database or reads or modifies package variables

For a parallel DML statement, any function call that cannot be executed in parallel causes the entire DML statement to be executed serially. For an INSERT ... SELECT or CREATE TABLE ... AS SELECT statement, function calls in the query portion are parallelized according to the parallel query rules in the previous paragraph. The query may be parallelized even if the remainder of the statement must execute serially, or vice versa.

Стоит поместить фынкцию в пакет, она начинает работать нормально в плане появляется PX COORDINATOR FORCED SERIAL
Проблема получается не с GTT, а вообще с видимостью незакоммиченных данных. Вопрос баг ли это или "фича".
10 янв 11, 14:53    [10048574]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
wurdu,

такое ощущение, что вот это не работает
that the code neither reads nor writes to the database

в отличии от
or reads or modifies package variables

То есть можем reads/writes(в автономной транзакции) в database и всё равно parallel. Думаю баг.
10 янв 11, 15:34    [10048760]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
wurdu
Member

Откуда: Владивосток
Сообщений: 4441
_Nikotin
wurdu
Мне не известны такие ограничения и на практике легко распараллелить запрос с участием временной и обычной таблицы.

А ограничения есть. Например Doc ID 457040.1, связанный с тем что NL+parallel не умеет нормально работать с GTT.
Ну там слишком обще сказано. Не работает вот так (t_tst - GTT):
SQL> select /*+ ordered use_nl(a b) parallel(a 2)*/ * from vz_tst a, t_tst b where a.name=b.name;

Execution Plan
----------------------------------------------------------
Plan hash value: 4067063161

-----------------------------------------------------------------------------
| Id  | Operation          | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |        |     1 |    24 |     3   (0)| 00:03:38 |
|   1 |  NESTED LOOPS      |        |     1 |    24 |     3   (0)| 00:03:38 |
|   2 |   TABLE ACCESS FULL| VZ_TST |     1 |    12 |     2   (0)| 00:02:20 |
|*  3 |   TABLE ACCESS FULL| T_TST  |     1 |    12 |     2   (0)| 00:02:20 |
-----------------------------------------------------------------------------

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

   3 - filter("A"."NAME"="B"."NAME")

Но можно вот так:
SQL> select /*+ ordered use_nl(a b) parallel(a 2) parallel(b 2)*/ * from vz_tst a, t_tst b where a.name=b.name;

Execution Plan
----------------------------------------------------------
Plan hash value: 1886939999

------------------------------------------------------------------------------------------------------------------
| Id  | Operation                | Name     | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |          |     1 |    24 |     3   (0)| 00:03:38 |        |      |            |
|   1 |  PX COORDINATOR          |          |       |       |            |          |        |      |            |
|   2 |   PX SEND QC (RANDOM)    | :TQ10001 |     1 |    24 |     3   (0)| 00:03:38 |  Q1,01 | P->S | QC (RAND)  |
|   3 |    NESTED LOOPS          |          |     1 |    24 |     3   (0)| 00:03:38 |  Q1,01 | PCWP |            |
|   4 |     BUFFER SORT          |          |       |       |            |          |  Q1,01 | PCWC |            |
|   5 |      PX RECEIVE          |          |       |       |            |          |  Q1,01 | PCWP |            |
|   6 |       PX SEND BROADCAST  | :TQ10000 |       |       |            |          |  Q1,00 | P->P | BROADCAST  |
|   7 |        PX BLOCK ITERATOR |          |     1 |    12 |     2   (0)| 00:02:20 |  Q1,00 | PCWC |            |
|   8 |         TABLE ACCESS FULL| VZ_TST   |     1 |    12 |     2   (0)| 00:02:20 |  Q1,00 | PCWP |            |
|   9 |     PX BLOCK ITERATOR    |          |     1 |    12 |     2   (0)| 00:02:20 |  Q1,01 | PCWC |            |
|* 10 |      TABLE ACCESS FULL   | T_TST    |     1 |    12 |     2   (0)| 00:02:20 |  Q1,01 | PCWP |            |
------------------------------------------------------------------------------------------------------------------

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

  10 - filter("A"."NAME"="B"."NAME")

SQL> select /*+ ordered use_nl(a b) parallel(b 2)*/ * from vz_tst a, t_tst b where a.name=b.name;

Execution Plan
----------------------------------------------------------
Plan hash value: 2853513771

-----------------------------------------------------------------------------------------------------------------
| Id  | Operation               | Name     | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |          |     1 |    24 |     4   (0)| 00:04:40 |        |      |            |
|   1 |  PX COORDINATOR         |          |       |       |            |          |        |      |            |
|   2 |   PX SEND QC (RANDOM)   | :TQ10001 |     1 |    24 |     4   (0)| 00:04:40 |  Q1,01 | P->S | QC (RAND)  |
|   3 |    NESTED LOOPS         |          |     1 |    24 |     4   (0)| 00:04:40 |  Q1,01 | PCWP |            |
|   4 |     BUFFER SORT         |          |       |       |            |          |  Q1,01 | PCWC |            |
|   5 |      PX RECEIVE         |          |       |       |            |          |  Q1,01 | PCWP |            |
|   6 |       PX SEND BROADCAST | :TQ10000 |       |       |            |          |        | S->P | BROADCAST  |
|   7 |        TABLE ACCESS FULL| VZ_TST   |     1 |    12 |     2   (0)| 00:02:20 |        |      |            |
|   8 |     PX BLOCK ITERATOR   |          |     1 |    12 |     2   (0)| 00:02:20 |  Q1,01 | PCWC |            |
|*  9 |      TABLE ACCESS FULL  | T_TST    |     1 |    12 |     2   (0)| 00:02:20 |  Q1,01 | PCWP |            |
-----------------------------------------------------------------------------------------------------------------

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

   9 - filter("A"."NAME"="B"."NAME")

10 янв 11, 15:57    [10048898]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
А вот это уже откровенный баг
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 
Connected as test_user

SQL> drop table t;
 
Table dropped
SQL> drop table gtt;
 
Table dropped
SQL> create table t as select 1 id from dual;
 
Table created
SQL> create global temporary table gtt (id number);
 
Table created
SQL> insert into gtt values (1);
 
1 row inserted
SQL> select /*+ parallel(t 2) */ distinct (select count(*) from gtt where t.id is not null) parallel from t;
 
  PARALLEL
----------
         0
SQL> select /*+ no_parallel*/ distinct (select count(*) from gtt where t.id is not null) noparallel from t;
 
NOPARALLEL
----------
         1
10 янв 11, 17:23    [10049361]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
Для полноты картины с функциями:
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 
Connected as test_user
 
SQL> 
SQL> drop table t;
 
Table dropped
SQL> drop table gtt;
 
Table dropped
SQL> create global temporary table gtt (id number);
 
Table created
SQL> create table t as select level id from dual connect by level <= 10;
 
Table created
SQL> create or replace function get_from_gtt1 return number is
  2    l_cnt number;
  3  begin
  4    select count(*) into l_cnt from gtt;
  5    return l_cnt;
  6  end;
  7  /
 
Function created
SQL> create or replace package p_test as
  2    g number := 0;
  3  end;
  4  /
 
Package created
SQL> create or replace function get_from_gtt2 return number is
  2    l_cnt number := p_test.g;
  3  begin
  4    select count(*) into l_cnt from gtt;
  5    return l_cnt;
  6  end;
  7  /
 
Function created
SQL> insert into gtt values (1);
 
1 row inserted
SQL> select /*+ parallel(t 2) */ distinct get_from_gtt1 from t;
 
GET_FROM_GTT1
-------------
            0
SQL> select /*+ parallel(t 2) */ distinct get_from_gtt2 from t;
 
GET_FROM_GTT2
-------------
            1
10 янв 11, 17:43    [10049459]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
-2-
Member

Откуда:
Сообщений: 15330
_Nikotin
А вот это уже откровенный баг
Если сбросить данные на диск (TEMP) перед выполнением?
10 янв 11, 18:45    [10049823]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
-2-,

То же самое повторяется на 10.2.0.4 и 11.1.0.7. Сброс ни чего не даёт, хотя да, можно было бы подумать что это из-за проблем с
When the slaves are reading from a disk, they are doing a direct I/O path read. This means it bypasses the buffer cache. In fact, slaves force blocks which have been updated, but not yet written to disk, to be flushed from the buffer cache to disk. Then it reads the data using direct path I/O.
10 янв 11, 21:14    [10050261]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
wurdu
Member

Откуда: Владивосток
Сообщений: 4441
_Nikotin
Для полноты картины с функциями: ...
Тут можно и без GTT.
11 янв 11, 00:39    [10050754]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
wurdu,

да и вообще
SQL> drop table t;
 
Table dropped
SQL> create table t (id number);
 
Table created
SQL> create or replace function get_from_t return number is
  2    l_cnt number;
  3  begin
  4    select count(*) into l_cnt from t;
  5    return l_cnt;
  6  end;
  7  /
 
Function created
SQL> insert into t values (1);
 
1 row inserted
SQL> select /*+ parallel(tt 2) */ get_from_tt, id from t;
 
GET_FROM_TT         ID
----------- ----------
          0          1
баг выходит и тут
If it is declared with the CREATE FUNCTION statement and the system can analyze the body of the PL/SQL code and determine that the code neither reads nor writes to the database or reads or modifies package variables
11 янв 11, 01:00    [10050787]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
вкралась ошибка:
_Nikotin
...
SQL> select /*+ parallel(tt 2) */ get_from_t, id from t;
...
11 янв 11, 01:06    [10050793]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
даже две:
_Nikotin
...
SQL> select /*+ parallel(t 2) */ get_from_t, id from t;
...
11 янв 11, 01:07    [10050796]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
Ещё небольшая ссылка по теме Performing PL/SQL functions in parallel which are not "pure"
...
Oracle executes a user-defined PL/SQL function in parallel only if it is a "pure" function. "Pure" means that it does not depend on a package state (it does not read or write variables defined on package/session level, in addition a really "pure" function should not read or write the database either, but here we focus on the package/session state/variables). The "purity" of a function can be determined in several ways:

* If it is a stand-alone PL/SQL function, Oracle is able to determine by itself (I think since Orace 8i) whether the function is pure or not. This does not apply to functions defined within a package
...
11 янв 11, 14:01    [10053173]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
3 копейки
Guest
На 10.2.0.4 win32:

SQL> select /*+ parallel(tt 2) */ get_from_t, id from t;

GET_FROM_T         ID
---------- ----------
         1          1

SQL> select /*+ parallel(t 2) */ get_from_t, id from t;

GET_FROM_T         ID
---------- ----------
         0          1

SQL> select /*+ parallel(tt 2) */ get_from_t, id from t tt;

GET_FROM_T         ID
---------- ----------
         0          1
11 янв 11, 15:09    [10053905]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание запросов с временными таблицами в Oracle11  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
3 копейки,

Правильно, это я таблицу и функцию переминовал для удобства tt -> t, а хинты забыл. В певром случае план без parallel поэтому верный результат. Если верить
randolf
, то такое поведение следует ожидать с 8i.
11 янв 11, 15:50    [10054375]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить