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

Modo più veloce per inserire, tramite script, in Oracle?

Problema

Il tempo di analisi può aumentare esponenzialmente con alcuni tipi di istruzioni, in particolare INSERT ALL . Ad esempio:

--Clear any cached statements, so we can consistently reproduce the problem.
alter system flush shared_pool;
alter session set sql_trace = true;

--100 rows
INSERT ALL
    INTO FileIds(Id,FileTypeGroupId) VALUES(1, 1)
    ...
    repeat 100 times
    ...
select * from dual;

--500 rows
INSERT ALL
    INTO FileIds(Id,FileTypeGroupId) VALUES(1, 1)
    ...
    repeat 500 times
    ...
select * from dual;

alter session set sql_trace = false;

Esegui il file di traccia tramite tkprof e puoi vedere che il tempo di analisi aumenta notevolmente per un numero elevato di righe. Ad esempio:

100 righe:

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.06       0.05          0          1          0           0
Execute      1      0.00       0.00          0        100        303         100
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.06       0.05          0        101        303         100

500 righe:

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1     14.72      14.55          0          0          0           0
Execute      1      0.01       0.02          0        502       1518         500
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2     14.74      14.58          0        502       1518         500

Soluzioni

  1. Dividi la tua affermazione di grandi dimensioni in diverse affermazioni più piccole. È difficile trovare la dimensione ottimale. In alcune versioni di Oracle esiste un numero magico di righe che causerà il problema. Di solito vado per circa 100 righe, sufficienti per ottenere la maggior parte dei vantaggi del raggruppamento delle istruzioni, ma abbastanza basse per evitare il bug di analisi. OPPURE...
  2. Prova insert into ... select ... from dual union all ... metodo invece. Di solito funziona molto più velocemente, anche se le prestazioni di analisi possono anche peggiorare notevolmente con le dimensioni.
  3. Aggiorna Oracle. Le prestazioni di analisi sono migliorate nelle versioni più recenti. Non riesco più a riprodurre questo problema nella versione 12.2.

Avviso

Non imparare la lezione sbagliata da questo. Se sei preoccupato per le prestazioni di SQL, il 99% delle volte è meglio raggruppare insieme cose simili invece di dividerle. Stai facendo le cose nel modo giusto, ti sei appena imbattuto in uno strano bug. (Ho cercato My Oracle Support ma non sono riuscito a trovare un bug ufficiale per questo.)