sql >> Database >  >> RDS >> Oracle

Hoe erg is het negeren van Oracle DUP_VAL_ON_INDEX uitzondering?

Ik zou normaal gesproken gewoon de DUP_VAL_ON_INDEX-uitzondering invoegen en vangen, omdat dit het eenvoudigst te coderen is. Dit is efficiënter dan het controleren op bestaan ​​voordat het wordt ingevoegd. Ik beschouw dit niet als een "slechte stank" (vreselijke uitdrukking!) omdat de uitzondering die we behandelen door Oracle is - het is niet alsof je je eigen uitzonderingen opheft als een stroomcontrolemechanisme.

Dankzij de opmerking van Igor heb ik hier nu twee verschillende benchmarks op uitgevoerd:(1) waarbij alle invoegpogingen behalve de eerste duplicaten zijn, (2) waarbij alle invoegingen geen duplicaten zijn. De werkelijkheid zal ergens tussen de twee gevallen in liggen.

Opmerking:tests uitgevoerd op Oracle 10.2.0.3.0.

Geval 1:Meestal duplicaten

Het lijkt erop dat de meest efficiënte benadering (met een significante factor) is om te controleren op bestaan ​​TIJDENS het invoegen:

prompt 1) Check DUP_VAL_ON_INDEX
begin
   for i in 1..1000 loop
      begin
         insert into hasviewed values(7782,20);
      exception
         when dup_val_on_index then
            null;
      end;
   end loop
   rollback;
end;
/

prompt 2) Test if row exists before inserting
declare
   dummy integer;
begin
   for i in 1..1000 loop
      select count(*) into dummy
      from hasviewed
      where objectid=7782 and userid=20;
      if dummy = 0 then
         insert into hasviewed values(7782,20);
      end if;
   end loop;
   rollback;
end;
/

prompt 3) Test if row exists while inserting
begin
   for i in 1..1000 loop
      insert into hasviewed
      select 7782,20 from dual
      where not exists (select null
                        from hasviewed
                        where objectid=7782 and userid=20);
   end loop;
   rollback;
end;
/

Resultaten (na één keer uitvoeren om overheadkosten te voorkomen):

1) Check DUP_VAL_ON_INDEX

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.54
2) Test if row exists before inserting

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.59
3) Test if row exists while inserting

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.20

Geval 2:geen duplicaten

prompt 1) Check DUP_VAL_ON_INDEX
begin
   for i in 1..1000 loop
      begin
         insert into hasviewed values(7782,i);
      exception
         when dup_val_on_index then
            null;
      end;
   end loop
   rollback;
end;
/

prompt 2) Test if row exists before inserting
declare
   dummy integer;
begin
   for i in 1..1000 loop
      select count(*) into dummy
      from hasviewed
      where objectid=7782 and userid=i;
      if dummy = 0 then
         insert into hasviewed values(7782,i);
      end if;
   end loop;
   rollback;
end;
/

prompt 3) Test if row exists while inserting
begin
   for i in 1..1000 loop
      insert into hasviewed
      select 7782,i from dual
      where not exists (select null
                        from hasviewed
                        where objectid=7782 and userid=i);
   end loop;
   rollback;
end;
/

Resultaten:

1) Check DUP_VAL_ON_INDEX

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.15
2) Test if row exists before inserting

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.76
3) Test if row exists while inserting

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.71

In dit geval wint DUP_VAL_ON_INDEX met een mijl. Merk op dat "selecteren voor invoegen" in beide gevallen het langzaamst is.

Het lijkt er dus op dat u optie 1 of 3 moet kiezen op basis van de relatieve kans dat inserts al dan niet duplicaten zijn.



  1. is er een limiet voor de bestandsgrootte bij het maken van een csv-bestand met php en mysql?

  2. Dialoogvenster niet geopend met GET_FILE_NAME Oracle Forms

  3. Hoe de Oracle-database te controleren op langlopende query's

  4. Gegevens ophalen uit twee tabellen, eerste tabeltekstgegevens, tweede tabelmediabeelden. de afbeeldingen mislukt