Oracle
 sql >> Base de données >  >> RDS >> Oracle

Oracle :existe-t-il une raison logique de ne pas utiliser l'exécution parallèle avec des sous-requêtes dans la liste SELECT ?

Chaque élément de cette liste est erroné.

(Au moins pour Oracle 11gR2, et probablement 10g également. La liste peut être exacte pour certaines versions obsolètes d'Oracle.)

Je recommande d'utiliser la documentation officielle d'Oracle dans la mesure du possible, mais le chapitre sur l'exécution parallèle n'est pas très précis.

Et même quand le manuel n'est pas faux, il est souvent trompeur, car l'exécution en parallèle est très compliquée. Si vous parcourez toute la documentation, vous constaterez qu'il existe environ 30 variables différentes qui déterminent le degré de parallélisme. Si jamais vous voyez une courte liste de contrôle des éléments, vous devriez être très sceptique. Ces listes de contrôle ne sont généralement que les éléments les plus pertinents à prendre en compte dans un contexte très spécifique.

Exemple :

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>

Pas d'indice parallèle, pas d'objets parallèles, pas d'analyse complète de la table, pas d'analyse de la plage d'index couvrant plusieurs partitions et une sous-requête scalaire.

Pas une seule condition remplie , mais la requête utilise toujours le parallélisme. (J'ai également vérifié v$px_process pour s'assurer que la requête utilise vraiment le parallélisme, et qu'il ne s'agit pas simplement d'un échec du plan d'explication.)

Cela signifie que la réponse à votre autre question est erronée.

Je ne sais pas exactement ce qui se passe dans ce cas, mais je pense que cela a à voir avec le FAST DUAL optimisation. Dans certains contextes, DUAL n'est pas utilisé comme table, il n'y a donc rien à paralléliser. C'est probablement un "bogue", mais si vous utilisez DUAL, vous ne voulez vraiment pas de parallélisme de toute façon. (Bien que je suppose que vous avez utilisé DUAL à des fins de démonstration et que votre véritable requête est plus compliquée. Si c'est le cas, vous devrez peut-être mettre à jour la requête avec un exemple plus réaliste.)