Problema
El tiempo de análisis puede aumentar exponencialmente con ciertos tipos de declaraciones, especialmente INSERT ALL
. Por ejemplo:
--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;
Ejecute el archivo de seguimiento a través de tkprof y podrá ver que el tiempo de análisis aumenta drásticamente para una gran cantidad de filas. Por ejemplo:
100 filas:
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 filas:
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
Soluciones
- Divida su declaración grande en varias declaraciones más pequeñas. Es difícil encontrar el tamaño óptimo. En algunas versiones de Oracle, hay un número mágico de filas que causarán el problema. Por lo general, busco alrededor de 100 filas, lo suficiente para obtener la mayoría de los beneficios de agrupar declaraciones, pero lo suficientemente bajo como para evitar el error de análisis. O...
- Pruebe
insert into ... select ... from dual union all ...
método en su lugar. Por lo general, se ejecuta mucho más rápido, aunque su rendimiento de análisis también puede degradarse significativamente con el tamaño. - Actualice Oracle. El rendimiento del análisis ha mejorado en las versiones más recientes. Ya no puedo reproducir este problema en la versión 12.2.
Advertencia
No aprendas la lección equivocada de esto. Si le preocupa el rendimiento de SQL, el 99 % de las veces es mejor agrupar cosas similares en lugar de separarlas. Estás haciendo las cosas de la manera correcta, acabas de encontrarte con un error extraño. (Busqué My Oracle Support pero no pude encontrar un error oficial para esto).