Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Szybszy sposób wstawiania za pomocą skryptu w Oracle?

Problem

Czas parsowania może wzrosnąć wykładniczo w przypadku niektórych typów instrukcji, zwłaszcza INSERT ALL . Na przykład:

--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;

Uruchom plik śledzenia przez tkprof, a zobaczysz, że czas analizy znacznie wzrasta dla dużej liczby wierszy. Na przykład:

100 wierszy:

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 wierszy:

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

Rozwiązania

  1. Podziel duże stwierdzenie na kilka mniejszych. Trudno znaleźć optymalny rozmiar. W niektórych wersjach Oracle istnieje magiczna liczba wierszy, które powodują problem. Zwykle wybieram około 100 wierszy — wystarczająco dużo, aby uzyskać większość korzyści z grupowania instrukcji, ale wystarczająco mało, aby uniknąć błędu parsowania. LUB...
  2. Wypróbuj insert into ... select ... from dual union all ... zamiast tego. Zwykle działa znacznie szybciej, chociaż wydajność analizowania może również znacznie pogorszyć się wraz z rozmiarem.
  3. Uaktualnij Oracle. Wydajność analizowania poprawiła się w nowszych wersjach. Nie mogę już odtworzyć tego problemu w wersji 12.2.

Ostrzeżenie

Nie wyciągaj z tego złej lekcji. Jeśli martwisz się wydajnością SQL, w 99% przypadków lepiej będzie grupować podobne rzeczy, zamiast je rozdzielać. Robisz rzeczy we właściwy sposób, właśnie natknąłeś się na dziwny błąd. (Przeszukałem My Oracle Support, ale nie mogłem znaleźć oficjalnego błędu w tym zakresie.)




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PLS-00428:w tej instrukcji SELECT oczekiwana jest klauzula INTO

  2. Usuń nagłówek kolumny do wyjściowego pliku tekstowego

  3. Zdanie BETWEEN kontra <=AND>=

  4. Jak uzyskać ostatni dzień miesiąca w Oracle?

  5. Migracja bazy danych Oracle z AWS EC2 do AWS RDS, część 3