2011-12-20 12 views
7

हटाएं कैस्केड अलग-अलग डिलीवरी कथन (एक एकल plsql ब्लॉक में निष्पादित) से अधिक कुशलता से एक तालिका पर हटा देता है?ओरेकल कैस्केड

उत्तर

17

क्या cascade delete करता मुद्दा अलग-अलग बयानों को हटाना है: आप इस तरह कुछ का उपयोग कर सकते हैं।

निम्नलिखित परीक्षण मामले की जांच:

delete from "<MY_SCHEMA_NAME>"."CHILD" where "PARENT_ID" = :1 
END OF STMT 
PARSE #6:c=0,e=182,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=1293353992514766 
EXEC#6:c=0,e=545,p=0,cr=2,cu=32,mis=1,r=10,dep=1,og=4,tim=1293353992515354 
EXEC#6:c=0,e=233,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992515644 
EXEC#6:c=0,e=238,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992515931 
EXEC#6:c=0,e=252,p=0,cr=2,cu=32,mis=0,r=10,dep=1,og=4,tim=1293353992516229 
EXEC#6:c=0,e=231,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992516507 
EXEC#6:c=0,e=227,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992516782 
EXEC#6:c=0,e=244,p=0,cr=2,cu=32,mis=0,r=10,dep=1,og=4,tim=1293353992517072 
EXEC#6:c=0,e=219,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992517337 
EXEC#6:c=0,e=236,p=0,cr=3,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992517622 
EXEC#6:c=0,e=235,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992517921 
EXEC#6:c=0,e=229,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992518196 
EXEC#6:c=0,e=246,p=0,cr=2,cu=32,mis=0,r=10,dep=1,og=4,tim=1293353992518487 
EXEC#6:c=0,e=234,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992518767 
EXEC#6:c=6999,e=570,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992519383 

ओरेकल प्रत्येक रिकॉर्ड यह है के लिए CHILD के खिलाफ एक हटाने बयान जारी करने वाले है:

create table parent 
(parent_id number, 
    parent_name varchar2(30), 
    constraint parent_pk primary key (parent_id) using index); 

create table child 
(child_id number, 
    parent_id number, 
    child_name varchar2(30), 
    constraint child_pk primary key (parent_id, child_id) using index, 
    constraint child_fk01 foreign key (parent_id) 
    references parent (parent_id) 
     on delete cascade; 
); 


insert into parent 
(parent_id, parent_name) 
select object_id, object_name from dba_objects where rownum <= 10000; 

begin 
    for i in 1..10 
    loop 
    insert into child 
     (child_id, parent_id, child_name) 
    select i, parent_id, parent_name 
     from parent; 
    end loop; 
end; 
/

exec dbms_stats.gather_table_stats (tabname => 'PARENT', cascade => true); 
exec dbms_stats.gather_table_stats (tabname => 'CHILD', cascade => true); 

exec dbms_monitor.session_trace_enable; 
alter table child drop constraint child_fk01; 
alter table child add constraint child_fk01 foreign key (parent_id) 
    references parent (parent_id) on delete cascade enable novalidate ; 
delete from parent; 
rollback; 

ट्रेस फ़ाइल में, आप इस तरह की एक पंक्ति मिलेगा PARENT में हटाना।

एक अलग सवाल होगा, जिनमें से दो अधिक कुशल हैं:

DELETE FROM CHILD WHERE PARENT_ID = 1; 
DELETE FROM PARENT WHERE PARENT_ID = 1; 

बनाम

DELETE FROM PARENT WHERE PARENT_ID = 1; 

दोनों on delete cascade साथ सक्षम होना चाहिए। आश्चर्यजनक रूप से पर्याप्त, ऊपर के पहले मामले में, ओरेकल बच्चे की मेज पर विदेशी कुंजी सूचकांक की जांच करेगा ताकि यह देखने के लिए कि कोई भी पंक्ति मौजूद है जिसके लिए एक कैस्केड की आवश्यकता होगी। यदि कोई पंक्ति मौजूद नहीं है, तो ओरेकल कैस्केड डिलीट निष्पादित नहीं करता है।

+0

+ 1 शानदार स्पष्टीकरण एडम –

+1

तो उत्तर कहां है? क्या अधिक कुशल है। – magulla

+0

@ मागुल्ला: ओरेकल में ज्यादातर चीजों के साथ, यह निर्भर करता है। हटाने से पहले कई बच्चे पंक्तियों को मैन्युअल रूप से हटाने के लिए और अधिक कुशल हो सकता है, लेकिन कुछ भी नहीं होने पर कुछ और बच्चों को डालने से कुछ भी सत्र रोकता नहीं है। यह मानते हुए कि ओरेकल प्रत्येक माता-पिता पंक्ति को हटाने के लिए हटा देता है यदि बच्चे मौजूद हैं, यदि प्रदर्शन सर्वोपरि है, तो एक ही कथन के साथ ब्याज की बाल तालिका की पंक्तियों को हटाने के लिए अपनी पूरी कोशिश करें अंगूठे का नियम होगा, लेकिन "बेहतर" प्रदर्शन की गारंटी नहीं है । –

5

आप इस तरह के दोनों विकल्पों की तुलना नहीं कर सकते। यह एक प्रदर्शन मुद्दा नहीं बल्कि अधिक डिजाइन अंडर संरचना है।

यदि आप प्राथमिक/विदेशी कुंजी का उपयोग करके अपना डेटाबेस डिज़ाइन करते हैं तो मैन्युअल रूप से खोज करने से कैस्केडिंग-डिलीट का उपयोग करके इसे हटाना आसान होगा, जहां आपके पास कॉलम और टेबल पर विदेशी कुंजी है और मशीनिंग एसक्यूएल कथन उत्पन्न करते हैं।

प्रमुख लाभ व्यापक-हटाता सुविधा के लिए है कि यह आप SQL कथन की मात्रा आप कार्रवाई

0

आप हटाना झरना चाहते हैं हटाने की कार्यवाही करने की जरूरत है और एक विदेशी कुंजी परिभाषित नहीं है कम करने के लिए अनुमति देता है

DELETE FROM my_table 
WHERE ROWID IN 
    (SELECT ROWID 
     FROM my_table 
     START WITH (condition_on_the_row_that_you_want_to_delete) 
     CONNECT BY PRIOR (primary_key) = (self_foreign_key) 
    ) 
+1

इस तरह के समाधान के नकारात्मक पक्ष यह होगा कि किसी भी पंक्ति में डाला गया है कि आपका सत्र हटाए जाने वाले सत्र को अभी भी नहीं डाला जाएगा - और अनाथाश्रम, जैसा कि आपने माता-पिता को मार डाला है, लेकिन बच्चे की पंक्तियां अभी भी डाली गई हैं। –

संबंधित मुद्दे