sql >> Base de Datos >  >> RDS >> Oracle

¿Una forma más rápida de insertar, a través de un script, en Oracle?

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

  1. 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...
  2. 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.
  3. 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).