Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Seberapa buruk mengabaikan pengecualian Oracle DUP_VAL_ON_INDEX?

Saya biasanya hanya memasukkan dan menjebak pengecualian DUP_VAL_ON_INDEX, karena ini adalah kode yang paling sederhana. Ini lebih efisien daripada memeriksa keberadaan sebelum memasukkan. Saya tidak menganggap melakukan ini sebagai "bau busuk" (frasa mengerikan!) karena pengecualian yang kami tangani diajukan oleh Oracle - ini tidak seperti menaikkan pengecualian Anda sendiri sebagai mekanisme kontrol aliran.

Berkat komentar Igor, saya sekarang telah menjalankan dua tolok ukur berbeda tentang ini:(1) di mana semua upaya penyisipan kecuali yang pertama adalah duplikat, (2) di mana semua sisipan bukan duplikat. Realitas akan terletak di suatu tempat di antara dua kasus.

Catatan:pengujian dilakukan pada Oracle 10.2.0.3.0.

Kasus 1:Sebagian besar duplikat

Tampaknya pendekatan yang paling efisien (dengan faktor signifikan) adalah memeriksa keberadaan SAAT memasukkan:

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;
/

Hasil (setelah dijalankan sekali untuk menghindari overhead parsing):

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

Kasus 2:tidak ada duplikat

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;
/

Hasil:

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

Dalam hal ini DUP_VAL_ON_INDEX menang sejauh satu mil. Perhatikan bahwa "pilih sebelum menyisipkan" adalah yang paling lambat dalam kedua kasus.

Jadi tampaknya Anda harus memilih opsi 1 atau 3 sesuai dengan kemungkinan relatif sisipan adalah duplikat atau bukan.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Melewati Null/string kosong ke prosedur tersimpan Oracle dari asp.net

  2. Bagaimana menjalankan pernyataan Oracle ini di JDBC

  3. Bagaimana cara meneruskan nilai ke operator IN secara dinamis?

  4. Hibernasi pembuatan kunci otomatis dengan MySQL dan Oracle

  5. Memetakan bidang di Oracle SQL Loader