मैं आम तौर पर केवल DUP_VAL_ON_INDEX अपवाद को सम्मिलित और ट्रैप करता हूं, क्योंकि यह कोड के लिए सबसे सरल है। डालने से पहले अस्तित्व की जांच करने से यह अधिक कुशल है। मैं इसे "बुरी गंध" (भयानक वाक्यांश!) नहीं मानता क्योंकि हम जो अपवाद संभालते हैं वह Oracle द्वारा उठाया जाता है - यह प्रवाह-नियंत्रण तंत्र के रूप में अपने स्वयं के अपवादों को बढ़ाने जैसा नहीं है।
इगोर की टिप्पणी के लिए धन्यवाद अब मैंने इस पर दो अलग-अलग बेंचमार्क चलाए हैं:(1) जहां पहले को छोड़कर सभी सम्मिलित प्रयास डुप्लिकेट हैं, (2) जहां सभी प्रविष्टियां डुप्लिकेट नहीं हैं। वास्तविकता कहीं न कहीं दो मामलों के बीच में होगी।
नोट:Oracle 10.2.0.3.0 पर किए गए परीक्षण।
मामला 1:अधिकतर डुप्लीकेट
ऐसा लगता है कि सबसे कुशल दृष्टिकोण (एक महत्वपूर्ण कारक द्वारा) डालने के दौरान अस्तित्व की जांच करना है:
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;
/
परिणाम (एक बार चलाने के बाद ओवरहेड पार्सिंग से बचने के लिए):
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
केस 2:कोई डुप्लीकेट नहीं
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;
/
परिणाम:
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
इस मामले में DUP_VAL_ON_INDEX एक मील से जीत जाता है। ध्यान दें कि "सम्मिलित करने से पहले चयन करें" दोनों ही मामलों में सबसे धीमा है।
तो ऐसा प्रतीत होता है कि आपको इंसर्ट के डुप्लीकेट होने या न होने की सापेक्ष संभावना के अनुसार विकल्प 1 या 3 चुनना चाहिए।