Problem
Die Analysezeit kann bei bestimmten Arten von Anweisungen exponentiell ansteigen, insbesondere bei INSERT ALL
. Zum Beispiel:
--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;
Führen Sie die Ablaufverfolgungsdatei durch tkprof, und Sie können sehen, dass die Analysezeit für eine große Anzahl von Zeilen dramatisch ansteigt. Zum Beispiel:
100 Zeilen:
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 Zeilen:
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
Lösungen
- Teilen Sie Ihre große Aussage in mehrere kleinere Aussagen auf. Es ist schwierig, die optimale Größe zu finden. Bei einigen Versionen von Oracle gibt es eine magische Anzahl von Zeilen, die das Problem verursachen. Normalerweise gehe ich für etwa 100 Zeilen - genug, um die meisten Vorteile der Gruppierung von Anweisungen zu nutzen, aber niedrig genug, um den Parsing-Bug zu vermeiden. ODER...
- Probieren Sie
insert into ... select ... from dual union all ...
Methode statt. Es läuft normalerweise viel schneller, obwohl seine Parsing-Leistung auch mit der Größe erheblich abnehmen kann. - Aktualisieren Sie Oracle. Die Analyseleistung wurde in neueren Versionen verbessert. Ich kann dieses Problem in Version 12.2 nicht mehr reproduzieren.
Warnung
Lernen Sie daraus nicht die falsche Lehre. Wenn Sie sich Sorgen um die SQL-Leistung machen, ist es in 99 % der Fälle besser, wenn Sie ähnliche Dinge zusammenfassen, anstatt sie zu trennen. Du machst die Dinge richtig, du bist gerade auf einen seltsamen Fehler gestoßen. (Ich habe My Oracle Support durchsucht, konnte aber keinen offiziellen Fehler dafür finden.)