sql >> Database >  >> RDS >> Oracle

Oracle:is er een logische reden om geen parallelle uitvoering te gebruiken met subquery's in de SELECT-lijst?

Elk item in die lijst is fout.

(In ieder geval voor Oracle 11gR2 en waarschijnlijk ook voor 10g. De lijst is mogelijk nauwkeurig voor sommige verouderde versies van Oracle.)

Ik raad aan om waar mogelijk de officiële Oracle-documentatie te gebruiken, maar het hoofdstuk over parallelle uitvoering is niet erg nauwkeurig.

En zelfs als de handleiding niet verkeerd is, is deze vaak misleidend, omdat parallelle uitvoering erg ingewikkeld is. Als je alle documentatie doorloopt, zul je zien dat er ongeveer 30 verschillende variabelen zijn die de mate van parallellisme bepalen. Als u ooit een korte checklist met items ziet, moet u zeer sceptisch zijn. Die checklists zijn meestal gewoon de meest relevante items om te overwegen in een zeer specifieke context.

Voorbeeld:

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>

Geen parallelle hint, geen parallelle objecten, geen volledige tabelscans, geen indexbereikscans die meerdere partities omspannen en een scalaire subquery.

Geen enkele voorwaarde voldaan , maar de query gebruikt nog steeds parallellisme. (Ik heb ook v$px_process geverifieerd om er zeker van te zijn dat de query echt parallellisme gebruikt, en dat het niet alleen een mislukte uitleg van het plan is.)

Dit betekent dat het antwoord op je andere vraag fout is.

Ik weet niet precies wat er in dat geval aan de hand is, maar ik denk dat het te maken heeft met de FAST DUAL optimalisatie. In sommige contexten wordt DUAL niet als tabel gebruikt, dus er valt niets te parallelliseren. Dit is waarschijnlijk een "bug", maar als je DUAL gebruikt, wil je toch echt geen parallellisme. (Hoewel ik aanneem dat je DUAL voor demonstratiedoeleinden hebt gebruikt, en je echte zoekopdracht ingewikkelder is. Als dat zo is, moet je de zoekopdracht mogelijk bijwerken met een realistischer voorbeeld.)




  1. Oracle-client ORA-12541:TNS:geen luisteraar

  2. RIJEN ophalen als KOLOMMEN (SQL Server dynamische PIVOT-query)

  3. SQLcl om gegevens over te zetten van Oracle naar PostgreSQL of YugabyteDB 🅾🐘🚀

  4. Hoeveel RAM heeft uw nieuwe databaseserver nodig?