sql >> Databasteknik >  >> RDS >> Oracle

Oracle:finns det någon logisk anledning att inte använda parallell exekvering med subqueries i SELECT-listan?

Varje objekt i den listan är fel.

(Åtminstone för Oracle 11gR2, och förmodligen 10g också. Listan kan vara korrekt för vissa föråldrade versioner av Oracle.)

Jag rekommenderar att du använder den officiella Oracle-dokumentationen när det är möjligt, men kapitlet om parallellkörning är inte särskilt exakt.

Och även när manualen inte är fel, är den ofta missvisande, eftersom parallellt utförande är mycket komplicerat. Om du går igenom all dokumentation hittar du att det finns ett 30-tal olika variabler som bestämmer graden av parallellitet. Om du någon gång ser en kort checklista med saker bör du vara mycket skeptisk. Dessa checklistor är vanligtvis bara de mest relevanta punkterna att överväga i ett mycket specifikt sammanhang.

Exempel:

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>

Ingen parallell ledtråd, inga parallella objekt, inga genomsökningar av hela tabeller, inga genomsökningar av indexintervall som spänner över flera partitioner och en skalär underfråga.

Inte ett enda villkor uppfylldes , men frågan använder fortfarande parallellism. (Jag har också verifierat v$px_process för att se till att frågan verkligen använder parallellism, och det är inte bara ett misslyckande med en förklarande plan.)

Det betyder att svaret på din andra fråga är fel.

Jag är inte säker på exakt vad som händer i det fallet, men jag tror att det har att göra med FAST DUAL optimering. I vissa sammanhang används inte DUAL som en tabell, så det finns inget att parallellisera. Detta är förmodligen en "bugg", men om du använder DUAL så vill du verkligen inte ha parallellitet ändå. (Även om jag antar att du använde DUAL i demonstrationssyfte, och din riktiga fråga är mer komplicerad. I så fall kan du behöva uppdatera frågan med ett mer realistiskt exempel.)




  1. Att byta Django-projekt från sqlite3-backend till postgresql misslyckas när datadump laddas

  2. MariaDB ROUND() vs TRUNCATE()

  3. Prestandamyter:Tabellvariabler finns alltid i minnet

  4. VÄLJ eller INFOGA en rad i ett kommando