Het verbetert de prestaties aanzienlijk (tientallen procenten gemiddeld) op zoekopdrachten die niet kunnen worden opgelost door een eenvoudige zoekopdracht met een enkele index, b.v. table joins.Het heeft echter de mogelijkheid om gegevens/toepassingsfouten te verbergen.
Laten we een tafel hebben:
create table t (id number(10,0), padding varchar2(1000));
--gebruik PK opzettelijk niet om het voorbeeld zo eenvoudig mogelijk te maken. De opvulling wordt gebruikt om de werkelijke gegevensbelasting in elk record te simuleren
met veel records:
insert into t (id, padding)
select rownum, rpad(' ', 1000) from dual connect by level < 10000
Als je nu iets vraagt als
select 1 into ll_exists
from t where id = 5;
de DB moet de hele tabel doorlopen of het het enige overeenkomende record in het eerste gegevensblok heeft gevonden (wat we trouwens niet kunnen weten omdat het op veel verschillende manieren kan worden ingevoegd) of in het laatste. Dat komt omdat het niet weet dat er maar één overeenkomend record is. Aan de andere kant, als je ... en rownum =1 gebruikt, kan het stoppen met het doorlopen van gegevens nadat het record is gevonden omdat je hebt verteld dat er geen ander overeenkomend record is (of niet nodig is).
Het nadeel is dat u met de rownum-beperking mogelijk niet-deterministische resultaten krijgt als de gegevens meer dan één mogelijk record bevatten. Als de query was
select id into ll_id
from t where mod (id, 2) = 1
and rownum = 1;
dan kan ik van de DB antwoord 1 zowel als 3 als 123 ontvangen ... bestelling is niet gegarandeerd en dit is het gevolg. (zonder de rownum-clausule zou ik een TOO_MANY_ROWS-uitzondering krijgen. Het hangt van de situatie af welke erger is)
Als je echt wilt weten welke tests bestaan, SCHRIJF HET dan OP DIE MANIER.
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;