Problém
Doba analýzy se může u určitých typů příkazů exponenciálně prodloužit, zejména INSERT ALL
. Například:
--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;
Spusťte trasovací soubor přes tkprof a uvidíte, jak se doba analýzy dramaticky prodlužuje u velkého počtu řádků. Například:
100 řádků:
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 řádků:
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
Řešení
- Rozdělte své velké prohlášení na několik menších. Je těžké najít optimální velikost. Na některých verzích Oracle je magický počet řádků, které způsobí problém. Obvykle jdu na asi 100 řádků – dost na to, abych získal většinu výhod seskupovacích příkazů, ale dostatečně nízko, abych se vyhnul chybě analýzy. NEBO...
- Zkuste
insert into ... select ... from dual union all ...
místo toho. Obvykle běží mnohem rychleji, i když jeho výkon při analýze může také výrazně klesat s velikostí. - Upgradujte Oracle. Výkon analýzy se v novějších verzích zlepšil. Tento problém již nemohu reprodukovat ve verzi 12.2.
Upozornění
Neberte si z toho špatnou lekci. Pokud se obáváte o výkon SQL, v 99 % případů je lepší podobné věci seskupit, než je rozdělovat. Děláte věci správně, právě jste narazili na podivného brouka. (Prohledal jsem My Oracle Support, ale nenašel jsem pro to oficiální chybu.)