Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle:Gibt es einen logischen Grund, die parallele Ausführung mit Unterabfragen in der SELECT-Liste nicht zu verwenden?

Jeder Eintrag in dieser Liste ist falsch.

(Zumindest für Oracle 11gR2 und wahrscheinlich auch für 10g. Die Liste kann für einige veraltete Versionen von Oracle zutreffend sein.)

Ich empfehle, wann immer möglich, die offizielle Oracle-Dokumentation zu verwenden, aber das Kapitel zur parallelen Ausführung ist nicht sehr genau.

Und selbst wenn das Handbuch nicht falsch ist, ist es oft irreführend, weil die parallele Ausführung sehr kompliziert ist. Wenn Sie die gesamte Dokumentation durchgehen, werden Sie feststellen, dass es ungefähr 30 verschiedene Variablen gibt, die den Grad der Parallelität bestimmen. Wenn Sie jemals eine kurze Checkliste mit Elementen sehen, sollten Sie sehr skeptisch sein. Diese Checklisten sind normalerweise nur die relevantesten Punkte, die in einem sehr spezifischen Kontext zu berücksichtigen sind.

Beispiel:

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>

Kein paralleler Hinweis, keine parallelen Objekte, keine vollständigen Tabellenscans, keine Indexbereichsscans, die sich über mehrere Partitionen erstrecken, und eine skalare Unterabfrage.

Keine einzige Bedingung erfüllt , die Abfrage verwendet jedoch weiterhin Parallelität. (Ich habe auch v$px_process verifiziert um sicherzustellen, dass die Abfrage wirklich Parallelität verwendet und es sich nicht nur um einen Explain-Plan-Fehler handelt.)

Das bedeutet, dass die Antwort auf Ihre andere Frage falsch ist.

Ich bin mir nicht sicher, was genau in diesem Fall vor sich geht, aber ich denke, es hat mit dem FAST DUAL zu tun Optimierung. In einigen Kontexten wird DUAL nicht als Tabelle verwendet, sodass nichts parallelisiert werden muss. Dies ist wahrscheinlich ein "Fehler", aber wenn Sie DUAL verwenden, möchten Sie sowieso keine Parallelität. (Obwohl ich annehme, dass Sie DUAL zu Demonstrationszwecken verwendet haben und Ihre echte Abfrage komplizierter ist. Wenn dies der Fall ist, müssen Sie die Abfrage möglicherweise mit einem realistischeren Beispiel aktualisieren.)