Yang salah dengan kursor adalah sering disalahgunakan, baik di Oracle
dan di MS SQL
.
Kursor adalah untuk menjaga hasil yang stabil yang dapat Anda ambil baris demi baris. Mereka dibuat secara implisit saat kueri Anda dijalankan, dan ditutup saat selesai.
Tentu saja menjaga hasil seperti itu memerlukan beberapa sumber daya:locks
, latches
, memory
, bahkan disk space
.
Semakin cepat sumber daya ini dibebaskan, semakin baik.
Membiarkan kursor tetap terbuka sama seperti membuka pintu lemari es
Anda tidak melakukannya selama berjam-jam tanpa kebutuhan, tetapi bukan berarti Anda tidak boleh membuka lemari es.
Artinya:
- Anda tidak mendapatkan hasil baris demi baris dan menjumlahkannya:Anda memanggil
SQL
SUM
sebagai gantinya. - Anda tidak menjalankan seluruh kueri dan mendapatkan hasil pertama dari kursor:Anda menambahkan
rownum <= 10
kondisi untuk permintaan Anda
, dll.
Adapun Oracle
, memproses kursor Anda di dalam prosedur memerlukan SQL/PLSQL context switch
yang terjadi setiap kali Anda mendapatkan hasil SQL
kueri keluar dari kursor.
Ini melibatkan pengiriman sejumlah besar data antara utas dan menyinkronkan utas.
Ini adalah salah satu hal yang paling menjengkelkan di Oracle
.
Salah satu konsekuensi yang kurang jelas dari perilaku tersebut adalah bahwa pemicu di Oracle harus dihindari jika memungkinkan.
Membuat pemicu dan memanggil DML
fungsinya sama dengan membuka kursor memilih baris yang diperbarui dan memanggil kode pemicu untuk setiap baris kursor ini.
Keberadaan pemicu saja (bahkan pemicu kosong) dapat memperlambat DML
operasi 10 times
atau lebih.
Skrip pengujian pada 10g
:
SQL> CREATE TABLE trigger_test (id INT NOT NULL)
2 /
Table created
Executed in 0,031 seconds
SQL> INSERT
2 INTO trigger_test
3 SELECT level
4 FROM dual
5 CONNECT BY
6 level <= 1000000
7 /
1000000 rows inserted
Executed in 1,469 seconds
SQL> COMMIT
2 /
Commit complete
Executed in 0 seconds
SQL> TRUNCATE TABLE trigger_test
2 /
Table truncated
Executed in 3 seconds
SQL> CREATE TRIGGER trg_test_ai
2 AFTER INSERT
3 ON trigger_test
4 FOR EACH ROW
5 BEGIN
6 NULL;
7 END;
8 /
Trigger created
Executed in 0,094 seconds
SQL> INSERT
2 INTO trigger_test
3 SELECT level
4 FROM dual
5 CONNECT BY
6 level <= 1000000
7 /
1000000 rows inserted
Executed in 17,578 seconds
1.47
detik tanpa pemicu, 17.57
detik dengan pemicu kosong tidak melakukan apa-apa.