sql >> Database >  >> RDS >> Oracle

Onder welke omstandigheden verhoogt ROWNUM=1 de prestaties in een bestaande syle-query aanzienlijk?

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;


  1. In MySQL werkt 'USE INDEX' niet, maar 'FORCE Index' lijkt goed te werken

  2. Hoe automatisch identiteit voor een Oracle-database genereren via Entity Framework?

  3. Hoe zorg je ervoor dat SQLAlchemy MySQL overschrijft bij update CURRENT_TIMESTAMP?

  4. Hoe versleutel ik dit wachtwoord met MD5 met PHP?