Problema
O tempo de análise pode aumentar exponencialmente com certos tipos de instruções, especialmente
INSERT ALL
. Por exemplo:--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;
Execute o arquivo de rastreamento por meio do tkprof e você verá que o tempo de análise aumenta drasticamente para um grande número de linhas. Por exemplo:
100 linhas:
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 linhas:
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
Soluções
- Divida sua declaração grande em várias declarações menores. É difícil encontrar o tamanho ideal. Em algumas versões do Oracle, há um número mágico de linhas que causarão o problema. Eu costumo usar cerca de 100 linhas - o suficiente para obter a maioria dos benefícios das instruções de agrupamento, mas baixo o suficiente para evitar o bug de análise. OU...
- Experimente
insert into ... select ... from dual union all ...
método em vez disso. Geralmente, ele é executado muito mais rápido, embora o desempenho da análise também possa diminuir significativamente com o tamanho. - Atualize o Oracle. O desempenho de análise melhorou nas versões mais recentes. Não consigo mais reproduzir este problema na versão 12.2.
Aviso
Não aprenda a lição errada com isso. Se você está preocupado com o desempenho do SQL, 99% das vezes é melhor agrupar coisas semelhantes em vez de separá-las. Você está fazendo as coisas do jeito certo, você acabou de encontrar um bug estranho. (Pesquisei no My Oracle Support, mas não consegui encontrar um bug oficial para isso.)