यदि आपके पास विशाल . होता आपके दृष्टिकोण के साथ समस्याएं, आप शायद कॉलम clean.id
. पर एक अनुक्रमणिका खो रहे हैं , जो आपके दृष्टिकोण के लिए आवश्यक है जब MERGE
dual
का उपयोग करता है प्रत्येक पंक्ति के स्रोत के रूप में।
जब आप id
. कह रहे हों तो इसकी संभावना कम होती है एक प्राथमिक कुंजी है ।
तो मूल रूप से आप सही सोच रहे हैं और आप देखेंगे निष्पादन योजना नीचे दिए गए के समान:
---------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------
| 0 | MERGE STATEMENT | | | | 2 (100)| |
| 1 | MERGE | CLEAN | | | | |
| 2 | VIEW | | | | | |
| 3 | NESTED LOOPS OUTER | | 1 | 40 | 2 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | DUAL | 1 | 2 | 2 (0)| 00:00:01 |
| 5 | VIEW | VW_LAT_A18161FF | 1 | 38 | 0 (0)| |
| 6 | TABLE ACCESS BY INDEX ROWID| CLEAN | 1 | 38 | 0 (0)| |
|* 7 | INDEX UNIQUE SCAN | CLEAN_UX1 | 1 | | 0 (0)| |
---------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
7 - access("CLEAN"."ID"=:ID)
तो निष्पादन योजना ठीक है और प्रभावी ढंग से काम करती है, लेकिन इसमें एक समस्या है।
याद रखें हमेशा आप एक इंडेक्स का उपयोग करते हैं, कुछ पंक्तियों को संसाधित करते समय आपको खुशी होगी, लेकिन यह स्केल नहीं होगा ।
अगर आप लाखों . को संसाधित कर रहे हैं रिकॉर्ड की संख्या में, आप दो चरणों वाली प्रक्रिया में वापस आ सकते हैं,
-
सभी पंक्तियों को एक अस्थायी तालिका में सम्मिलित करें
-
एक एकल
MERGE
निष्पादित करें अस्थायी तालिका का उपयोग कर बयान
बड़ा लाभ यह है कि Oracle एक hash join
open खोल सकता है और मिलियन . में से प्रत्येक के लिए अनुक्रमणिका पहुंच से छुटकारा पाएं पंक्तियाँ।
यहां clean
. के परीक्षण का एक उदाहरण दिया गया है 1M id
. के साथ शुरू की गई तालिका (दिखाया नहीं गया) और 1M इंसर्ट और 1M अपडेट कर रहा है:
n = 1000000
data2 = [{"id" : i, "xcount" :1} for i in range(2*n)]
sql3 = """
insert into tmp (id,count)
values (:id,:xcount)"""
sql4 = """MERGE into clean USING tmp on (clean.id = tmp.id)
when not matched then insert (id, count) values (tmp.id, tmp.count)
when matched then update set clean.count= clean.count + tmp.count"""
cursor.executemany(sql3, data2)
cursor.execute(sql4)
परीक्षण लगभग चलता है। 10 सेकंड, जो कि आप में से आधे से भी कम है MERGE
. के साथ संपर्क करें dual
. का उपयोग करना ।
यदि यह अभी भी पर्याप्त नहीं है, तो आपको समानांतर विकल्प . का उपयोग करना होगा ।