Itu meningkatkan kinerja secara signifikan (rata-rata puluhan persen) pada kueri yang tidak dapat diselesaikan dengan pencarian indeks tunggal sederhana mis. tabel bergabung. Namun memiliki potensi untuk menyembunyikan kesalahan data/aplikasi.
Mari kita punya meja:
create table t (id number(10,0), padding varchar2(1000));
--sengaja tidak menggunakan PK untuk membuat contoh sesederhana mungkin. Padding digunakan untuk mensimulasikan beban data nyata di setiap record
dengan banyak catatan:
insert into t (id, padding)
select rownum, rpad(' ', 1000) from dual connect by level < 10000
Sekarang jika Anda menanyakan sesuatu seperti
select 1 into ll_exists
from t where id = 5;
DB harus melalui seluruh tabel apakah ia menemukan satu-satunya catatan yang cocok di blok data pertama (yang omong-omong kita tidak bisa tahu karena bisa dimasukkan dengan berbagai cara) atau yang terakhir. Itu karena tidak tahu bahwa hanya ada satu record yang cocok. Di sisi lain jika Anda menggunakan ... dan rownum =1 maka ia dapat berhenti melintasi data setelah catatan ditemukan karena Anda memberi tahunya bahwa tidak ada (atau tidak diperlukan) catatan lain yang cocok.
Kekurangannya adalah bahwa dengan batasan rownum Anda mungkin mendapatkan hasil yang tidak pasti jika data berisi lebih dari satu kemungkinan record.Jika kuerinya
select id into ll_id
from t where mod (id, 2) = 1
and rownum = 1;
maka saya dapat menerima dari DB jawaban 1 dan juga 3 serta 123 ... pesanan tidak dijamin dan ini konsekuensinya. (tanpa klausa rownum saya akan mendapatkan pengecualian TOO_MANY_ROWS. Tergantung situasi mana yang lebih buruk)
Jika Anda benar-benar menginginkan kueri yang menguji keberadaan, maka TULISLAH DENGAN CARA ITU.
begin
select 'It does'
into ls_exists
from dual where
exists (your_original_query_without_rownum);
do_something_when_it_does_exist
exception
when no_data_found then
do_something_when_it_doesn't_exist
end;