Masalah
Waktu penguraian dapat meningkat secara eksponensial dengan jenis pernyataan tertentu, terutama INSERT ALL
. Misalnya:
--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;
Jalankan file jejak melalui tkprof, dan Anda dapat melihat waktu Parse meningkat secara dramatis untuk sejumlah besar baris. Misalnya:
100 baris:
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 baris:
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
Solusi
- Pisahkan pernyataan besar Anda menjadi beberapa pernyataan kecil. Sulit untuk menemukan ukuran yang optimal. Pada beberapa versi Oracle ada sejumlah baris ajaib yang akan menyebabkan masalah. Saya biasanya menggunakan sekitar 100 baris - cukup untuk mendapatkan sebagian besar manfaat dari pernyataan pengelompokan, tetapi cukup rendah untuk menghindari bug penguraian. ATAU...
- Coba
insert into ... select ... from dual union all ...
metode sebagai gantinya. Biasanya berjalan lebih cepat, meskipun kinerja penguraiannya juga dapat menurun secara signifikan dengan ukuran. - Perbarui Oracle. Performa penguraian telah meningkat di versi yang lebih baru. Saya tidak dapat mereproduksi masalah ini lagi di versi 12.2.
Peringatan
Jangan mengambil pelajaran yang salah dari ini. Jika Anda khawatir tentang kinerja SQL, 99% dari waktu Anda lebih baik mengelompokkan hal-hal serupa bersama-sama daripada memisahkannya. Anda melakukan hal-hal dengan cara yang benar, Anda baru saja mengalami bug aneh. (Saya mencari Dukungan Oracle Saya tetapi tidak dapat menemukan bug resmi untuk ini.)