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
- 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...
- 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. - 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.)