Oracle
 sql >> Database >  >> RDS >> Oracle

Oracle:esiste una ragione logica per non utilizzare l'esecuzione parallela con le sottoquery nell'elenco SELECT?

Ogni elemento in quell'elenco è sbagliato.

(Almeno per Oracle 11gR2 e probabilmente anche 10g. L'elenco potrebbe essere accurato per alcune versioni obsolete di Oracle.)

Consiglio di utilizzare la documentazione ufficiale di Oracle quando possibile, ma il capitolo sull'esecuzione parallela non è molto accurato.

E anche quando il manuale non è sbagliato, spesso è fuorviante, perché l'esecuzione parallela è molto complicata. Se esamini tutta la documentazione scoprirai che ci sono circa 30 diverse variabili che determinano il grado di parallelismo. Se vedi una breve lista di controllo di elementi, dovresti essere molto scettico. Queste liste di controllo sono di solito solo gli elementi più rilevanti da considerare in un contesto molto specifico.

Esempio:

SQL> --Create a table without any parallel settings
SQL> create table parallel_test(a number primary key, b number);

Table created.

SQL> --Create some test data
SQL> insert into parallel_test
  2  select level, level from dual connect by level <= 100000;

100000 rows created.

SQL> commit;

Commit complete.

SQL> --Force the session to run the query in parallel
SQL> alter session force parallel query;

Session altered.
SQL> --Generate explain plan
SQL> explain plan for
  2  select a
  3     ,(
  4             select a
  5             from parallel_test parallel_test2
  6             where parallel_test2.a = parallel_test.a
  7     )
  8  from parallel_test;

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3823224058

---------------------------------------------------------------------------------------------------------------------
| Id  | Operation               | Name         | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |              |   116K|  1477K|     9   (0)| 00:00:01 |        |      |            |
|*  1 |  INDEX UNIQUE SCAN      | SYS_C0028894 |     1 |    13 |     1   (0)| 00:00:01 |        |      |            |
|   2 |  PX COORDINATOR         |              |       |       |            |          |        |      |            |
|   3 |   PX SEND QC (RANDOM)   | :TQ10000     |   116K|  1477K|     9   (0)| 00:00:01 |  Q1,00 | P->S | QC (RAND)  |
|   4 |    PX BLOCK ITERATOR    |              |   116K|  1477K|     9   (0)| 00:00:01 |  Q1,00 | PCWC |            |
|   5 |     INDEX FAST FULL SCAN| SYS_C0028894 |   116K|  1477K|     9   (0)| 00:00:01 |  Q1,00 | PCWP |            |
---------------------------------------------------------------------------------------------------------------------

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

   1 - access("PARALLEL_TEST2"."A"=:B1)

Note
-----
   - dynamic sampling used for this statement (level=2)

21 rows selected.

SQL>

Nessun suggerimento parallelo, nessun oggetto parallelo, nessuna scansione completa della tabella, nessuna scansione dell'intervallo di indici su più partizioni e una sottoquery scalare.

Nessuna condizione soddisfatta , tuttavia la query utilizza ancora il parallelismo. (Ho anche verificato v$px_process per assicurarsi che la query utilizzi davvero il parallelismo e non si tratti solo di un errore del piano di spiegazione.)

Ciò significa che la risposta all'altra tua domanda è sbagliata.

Non sono sicuro di cosa stia succedendo esattamente in quel caso, ma penso che abbia a che fare con il FAST DUAL ottimizzazione. In alcuni contesti, DUAL non viene utilizzato come tabella, quindi non c'è nulla da parallelizzare. Questo è probabilmente un "bug", ma se stai usando DUAL, non vuoi comunque il parallelismo. (Anche se suppongo che tu abbia utilizzato DUAL a scopo dimostrativo e la tua vera query è più complicata. In tal caso, potresti dover aggiornare la query con un esempio più realistico.)