Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Maneira mais rápida de Inserir, via script, no Oracle?


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