Той подобрява значително производителността (средно десетки процента) на заявки, които не могат да бъдат решени чрез просто търсене в един индекс, напр. присъединява се към таблица. Въпреки това има потенциал да скрие грешка в данните/приложението.
Да имаме маса:
create table t (id number(10,0), padding varchar2(1000));
--умишлено не използвайте PK, за да направите примера възможно най-прост. Подпълването се използва за симулиране на реално натоварване на данни във всеки запис
с много записи:
insert into t (id, padding)
select rownum, rpad(' ', 1000) from dual connect by level < 10000
Сега, ако попитате нещо като
select 1 into ll_exists
from t where id = 5;
DB трябва да премине през цялата таблица, независимо дали е намерил единствения съответстващ запис в първия блок от данни (който между другото не можем да знаем, защото може да бъде вмъкнат по много различни начини) или в последния. Това е така, защото не знае, че има само един съответстващ запис. От друга страна, ако използвате ... и rownum =1, той може да спре преминаването през данни, след като записът бъде намерен, защото сте му казали, че няма (или не е необходим) друг съответстващ запис.
Недостатъкът е, че с ограничението rownum може да получите недетерминирани резултати, ако данните съдържат повече от един възможен запис. Ако заявката беше
select id into ll_id
from t where mod (id, 2) = 1
and rownum = 1;
тогава може да получа от DB отговор 1, както и 3, както и 123 ... редът не е гарантиран и това е следствието. (без клаузата rownum бих получил TOO_MANY_ROWS изключение. Зависи от ситуацията кое е по-лошо)
Ако наистина искате заявка, която тества съществуването, тогава Я НАПИШЕТЕ ТАКА.
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;