2010-02-13 16 views
7

मैं एक इनओडीबी तालिका पर एक सशर्त डिलीट करने का एक तरीका खोजने का प्रयास कर रहा हूं जिसमें लाखों रिकॉर्ड हैं, इसे लॉक किए बिना (इस प्रकार वेबसाइट को नीचे नहीं लाया जा रहा है)।लाखों रिकॉर्ड्स के साथ तालिका से हटाना

मैंने mysql.com पर जानकारी खोजने की कोशिश की है, लेकिन इसका कोई फायदा नहीं हुआ है। आगे बढ़ने के बारे में कोई सुझाव?

+0

क्या इस तालिका में बहुत सारे इंडेक्स हैं? –

+0

कॉलम इंडेक्स जो शर्तों को संभाल लेंगे। फिर साइट पर यातायात कम होने पर हटाएं (@ रात शायद)। –

+0

यह भी देखें http://stackoverflow.com/questions/23193761/delete-operation-locks-whole-table-in-innodb जो अंतराल लॉकिंग का उल्लेख करता है – rogerdpack

उत्तर

8

मुझे नहीं लगता कि लॉक किए बिना हटाना संभव है। उस ने कहा, मुझे नहीं लगता कि आप जिस रिकॉर्ड को हटाना चाहते हैं उसे लॉक करना एक समस्या है। दूसरी पंक्तियों को लॉक करने में समस्या क्या होगी। http://dev.mysql.com/doc/refman/5.0/en/innodb-locks-set.html

मैं क्या सुझाव है, कोशिश करते हैं और एक लाख एकल पंक्ति को हटा देता है क्या करना है:

मैं उस विषय यहाँ पर कुछ जानकारी मिल गया। मुझे लगता है कि यदि आप एक ही लेनदेन में उन सभी को करते हैं, तो प्रदर्शन को बहुत ज्यादा नुकसान नहीं पहुंचाया जाना चाहिए। ताकि आप की तरह कुछ मिलेगा:

START TRANSACTION; 

DELETE FROM tab WHERE id = 1; 
.. 
.. 
DELETE FROM tab WHERE id = x; 

COMMIT; 

आप इस विधि से अधिक की तरह

SELECT CONCAT('DELETE FROM tab WHERE id = ', id) 
FROM tab 
WHERE <some intricate condition that selects the set you want to delete> 

तो लाभ कुछ कर के बजाय करके आवश्यक statments उत्पन्न कर सकते हैं:

DELETE FROM tab 
WHERE <some intricate condition that selects the set you want to delete> 

कि है पहले दृष्टिकोण में आप केवल उस रिकॉर्ड को लॉक करते हैं जिसे आप हटा रहे हैं, जबकि दूसरे दृष्टिकोण में आप अन्य रिकॉर्ड लॉक करने का जोखिम चला सकते हैं जो पंक्ति के समान सीमा में होता है आप हटा रहे हैं

+0

+1, वादा समाधान! क्या आपने कभी इस दृष्टिकोण का अभ्यास किया है? – Frunsi

+0

@ फ्रांसी: मैं ईमानदारी से स्वीकार करता हूं कि मैंने नहीं किया है।आमतौर पर, मैं एक लाख पंक्तियों को हटाने के साथ एक मुद्दे के ज्यादा नहीं है, लेकिन फिर सिस्टम मेरे द्वारा प्रबंधित एक ही समय में कई उपयोगकर्ताओं ने टक्कर मार दी नहीं जा रहा है। –

5

यदि यह आपके एप्लिकेशन को फिट करता है, तो आप हटाने के लिए पंक्तियों की संख्या को सीमित कर सकते हैं, और हटाने को दोहराने के लिए क्रोनबॉज सेट कर सकते हैं। उदा .:

DELETE FROM tab WHERE .. LIMIT 1000 

मैं इस एक ऐसी ही स्थिति में अच्छा समझौता हो पाया।

+0

मुझे लगता है कि इस दृष्टिकोण के साथ समस्या यह है कि सेट को अलग करने के बाद LIMIT का मूल्यांकन किया जाता है । तो 'WHERE' लागू किया गया है, जो पंक्तियों को लॉक कर सकता है जो कि आपके द्वारा हटाए जा रहे पंक्तियों के समान सीमा में होते हैं। तथ्य यह है कि आप केवल सीमित संख्या को हटाते हैं, इस तथ्य को नहीं बदलेगा कि रिकॉर्ड पहले ही लॉक हो चुके हैं। यह विधि क्या करती है लेनदेन के आकार को छोटा रखना, जो भी अच्छा है। लेकिन जहां तक ​​मैं समझता हूं, यह नकली लॉकिंग को रोकता नहीं है। –

+0

@ रोलैंड: आप सही हो सकते हैं। यह समाधान आदर्श नहीं हो सकता है, लेकिन अभ्यास में ठीक काम करता है (सीमित डिलीट तेज़ है, इसलिए ताले बहुत छोटे टाइमपैन के लिए हैं, सीमा पैरामीटर वास्तविक जीवन डेटा में ट्यून किया जा सकता है)। मैंने इस दृष्टिकोण का उपयोग करने से पहले कुछ बेंचमार्क किए थे, और सभी सीमित डिलीटों का संचित समय एक गैर-सीमित एक से कम समय में समाप्त हुआ (लेकिन इस समय, यह MySQL 3.x और MyISAM तालिकाओं का उपयोग करता था)। यह अभी भी काम करता है, लेकिन वर्तमान MySQL और InnoDB तालिकाओं पर बेंचमार्क विवरण में कुछ प्रकाश लाएगा .. – Frunsi

+0

हाँ मुझे लगता है कि यह कहना सुरक्षित है कि आप जिस परिदृश्य का वर्णन करते हैं, एक टेबल 9 साल से अधिक पुराने संस्करण पर MyISAM इंजन लॉक कर रहा है इनो डीबी इंजन की तुलना में उत्पाद जिसमें बहु-संस्करण समवर्ती नियंत्रण और पंक्ति-स्तर लॉकिंग दोनों शामिल हैं, वास्तव में कुछ अलग हो सकते हैं: पी –

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