2012-02-06 10 views
49

मुझे किसी विशेष कुंजी के साथ रिकॉर्ड के सभी फ़ील्ड के मानों को सेट करना है (कुंजी वास्तव में समग्र है), रिकॉर्ड को सम्मिलित करना यदि अभी तक ऐसी कुंजी के साथ कोई रिकॉर्ड नहीं है।MySQL में `REPLACE` और 'INSERT ... पर लागू कुंजी अपडेट' के बीच व्यावहारिक मतभेद क्या हैं?

REPLACE नौकरी करने के लिए प्रतीत होता है, लेकिन साथ ही इसके मैनुअल पेज INSERT ... ON DUPLICATE KEY UPDATE का सुझाव देता है।

उनमें से मुझे क्या बेहतर चुनना चाहिए और क्यों?

REPLACE का एकमात्र "दुष्प्रभाव" मेरे दिमाग में आता है कि यह ऑटोइनक्रिकमेंट मानों को बढ़ाएगा (सौभाग्य से मैं किसी का उपयोग नहीं करता) जबकि INSERT ... ON DUPLICATE KEY UPDATE शायद नहीं होगा। ध्यान में रखने के लिए अन्य व्यावहारिक मतभेद क्या हैं? REPLACE पर विशेष मामलों में INSERT ... ON DUPLICATE KEY UPDATE और इसके विपरीत क्या पसंद किया जा सकता है?

+0

सम्मिलित करें ... पर नकली चाबी अद्यतन वास्तव में करता भी autoincrement काउंटर बढ़ाने के। रिकॉर्ड अपडेट होने के लिए नहीं, लेकिन अगले रिकॉर्ड के लिए डाला गया। तो यदि उच्चतम आईडी 10 है और आप एक डुप्लिकेट डालने के लिए करते हैं, और फिर एक नया अद्वितीय मान डालता है, तो पंक्ति की आईडी 12 हो जाएगी। – marlar

उत्तर

83

REPLACE आंतरिक रूप से एक डिलीट निष्पादित करता है और फिर एक सम्मिलित करता है। यदि आपके पास उस पंक्ति पर इंगित एक विदेशी कुंजी बाधा है तो इससे समस्याएं पैदा हो सकती हैं। इस स्थिति में REPLACE असफल हो सकता है या खराब हो सकता है: यदि आपकी विदेशी कुंजी को कैस्केड करने के लिए सेट किया गया है, तो REPLACE अन्य तालिकाओं से पंक्तियां हटा दी जाएगी। यह तब भी हो सकता है जब REPLACE ऑपरेशन से पहले और बाद में बाधा संतुष्ट हो।

INSERT ... ON DUPLICATE KEY UPDATE का उपयोग इस समस्या से बचाता है और इसलिए इसे पसंद किया जाता है।

+4

+1 यह प्रबुद्ध है! मैं इस से काटा गया था और इसे कभी नहीं समझा। –

+1

अच्छा जवाब, लेकिन मेरे वास्तविक मामले में इस समस्या को पूरा नहीं किया जा रहा है। टक्कर का मौका 50/50 माना जा सकता है। तब मुझे क्या चुनना चाहिए? और 'INSERT ... डिप्लिकेट कुंजी अपडेट पर' काफी "बेहतर" दिखता है, तो किस विशेष मामले में "स्थान" बेहतर विकल्प हो सकता है? – Ivan

+1

मैंने थोड़ा सा शोध किया है और जहां तक ​​मैं कह सकता हूं, INSERT के बजाय REPLACE का उपयोग करने का कोई आम कारण नहीं है ... डिप्लिकेट कुंजी अपडेट पर। यह अनिवार्य रूप से एक विरासत सुविधा है। जब तक कोई विशेष कारण नहीं है कि आपका कोड पंक्तियों पर निर्भर करता है और फिर से जोड़ा जाता है, तो इंडेक्स और ऑटो-वृद्धि मूल्यों पर जुड़े प्रभावों के साथ, इसका उपयोग करने का कोई कारण नहीं होता है। –

1

प्रतिस्थापन लगता है कि यह इस मामले में दो संचालन करता है कि कुंजी पहले से मौजूद है। शायद इसका मतलब है कि दोनों के बीच गति अंतर है?

(सम्मिलित) एक अद्यतन एक बनाम + एक डालने (बदलें)

संपादित करें हटाएँ: मेरे निहितार्थ यह है कि जगह ले धीमी हो सकती है वास्तव में पूरी तरह गलत है। खैर, इस ब्लॉग के अनुसार वैसे भी पोस्ट ... http://www.tokutek.com/2010/07/why-insert-on-duplicate-key-update-may-be-slow-by-incurring-disk-seeks/

5

जब INSERT ... ON DUPLICATE KEY UPDATE के बजाय REPLACE का उपयोग कर, मैं कभी कभी कुंजी ताला या गतिरोध समस्याओं का निरीक्षण जब कई प्रश्नों किसी कुंजी के लिए जल्दी से पहुंचें। उत्तरार्द्ध की परमाणुता (कैस्केड डिलीट न होने के अलावा) इसका उपयोग करने के लिए और भी अधिक कारण है।

2

INSERT पर कौन से विशेष मामलों को प्रतिस्थापित किया जा सकता है ... डिप्लिकेट कुंजी अपडेट और इसके विपरीत?

मैं सिर्फ कठिन रास्ता है कि एक संघीय भंडारण इंजन के साथ टेबल के मामले में INSERT...ON DUPLICATE KEY UPDATE बयान स्वीकार कर रहे हैं पता चला है, लेकिन (असफल एक त्रुटि 1022 के साथ: नहीं लिख सकता, नकल तालिका में कुंजी .. ।) यदि डुप्लिकेट-कुंजी उल्लंघन होता है - MySQL संदर्भ मैनुअल के this page पर संबंधित बुलेट बिंदु देखें।

सौभाग्य से, मैं का उपयोग INSERT...ON DUPLICATE KEY UPDATE के बजाय मेरे फेरबदल तालिका में परिवर्तनों को प्रतिलिपि बनाने के वांछित परिणाम प्राप्त करने के लिए मेरे ट्रिगर के बाद में करने में सक्षम था।

1

यदि आप सभी कॉलम सूचीबद्ध नहीं करते हैं, तो मुझे लगता है कि REPLACE किसी भी अनियमित कॉलम को प्रतिस्थापित पंक्तियों में उनके डिफ़ॉल्ट मानों के साथ रीसेट कर देगा। ON DUPLICATE KEY UPDATE अनियमित कॉलम अपरिवर्तित छोड़ देगा।

24

प्रदर्शन के मामले में सवाल का जवाब करने के लिए, मैं का उपयोग कर परीक्षण किया दोनों तरीकों

बदलें में शामिल है:
1.Try तालिका
2. 1 विफल रहता है, पंक्ति को हटा पर डालने और पर नकली चाबी अद्यतन

सम्मिलित डालने नई पंक्ति शामिल है:
1.Try तालिका
2. यदि 1 विफल रहता है, अद्यतन पंक्ति
पर डालने यदि शामिल सभी कदम आवेषण हैं, तो प्रदर्शन में कोई अंतर नहीं होना चाहिए। गति को शामिल अद्यतनों की संख्या पर निर्भर होना है। सबसे बुरा मामला यह है कि जब सभी बयान अद्यतन होते हैं

मैंने 62,510 प्रविष्टियों (केवल अपडेट) सहित मेरी इनो डीबी तालिका पर दोनों बयानों की कोशिश की है। camparing गति पर: 77.411 सेकंड पर नकली चाबी अद्यतन
सम्मिलित:
में बदलें 2.446 सेकंड

Insert on Duplicate Key update is almost 32 times faster. 

तालिका आकार: एक अमेज़न m3.medium पर 12 कॉलम के साथ 1,249,250 पंक्तियों

+0

कूल आंकड़े का उपयोग करता हूं, क्या आपने' डुप्लिकेट कुंजी प्रतिस्थापन पर डालें 'का प्रयास किया था? क्या यह धीमा था? – radtek

0

"यह यह संभव है कि डुप्लिकेट-कुंजी त्रुटि के मामले में, एक स्टोरेज इंजन डिलीट प्लस डालने के बजाए एक अद्यतन के रूप में REPLACE को निष्पादित कर सकता है, लेकिन अर्थशास्त्र समान हैं। "

http://dev.mysql.com/doc/refman/5.7/en/replace.html

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