Det förbättrar prestandan avsevärt (tiotals procent i genomsnitt) på frågor som inte kan lösas genom enkel indexsökning, t.ex. tabellen joins. Den har dock en potential att dölja data/applikationsfel.
Låt oss ha ett bord:
create table t (id number(10,0), padding varchar2(1000));
--Använd inte PK med avsikt för att göra exemplet så enkelt som möjligt. Utfyllnaden används för att simulera verklig databelastning i varje post
med många poster:
insert into t (id, padding)
select rownum, rpad(' ', 1000) from dual connect by level < 10000
Nu om du frågar något liknande
select 1 into ll_exists
from t where id = 5;
DB:n måste gå igenom hela tabellen om den hittade den enda matchande posten i det första datablocket (vilket vi för övrigt inte kan veta eftersom det kan infogas på många olika sätt) eller i det sista. Det beror på att den inte vet att det bara finns en matchande post. Å andra sidan om du använder ... och rownum =1 så kan den sluta gå igenom data efter att posten har hittats eftersom du sa till den att det inte finns (eller inte behövs) en annan matchande post.
Nackdelen är att med rownum-begränsningen kan du få obestämda resultat om data innehåller mer än en möjlig post. Om frågan var
select id into ll_id
from t where mod (id, 2) = 1
and rownum = 1;
då får jag kanske från DB svar 1 såväl som 3 samt 123 ... ordning är inte garanterad och detta är konsekvensen. (utan rownum-satsen skulle jag få ett TOO_MANY_ROWS undantag. Det beror på situationen vilken som är värst)
Om du verkligen vill fråga vilka som testar existensen så SKRIV DET SÅ.
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;