MyISAM बनाम InnoDB [बंद]


857

मैं एक ऐसी परियोजना पर काम कर रहा हूं जिसमें बहुत सारे डेटाबेस शामिल हैं, मैं कहता हूं ( 70% आवेषण और 30% रीड्स )। इस अनुपात में वे अपडेट भी शामिल होंगे जिन्हें मैं एक पढ़ने और एक लिखने के लिए मानता हूं। रीड्स गंदे हो सकते हैं (जैसे मुझे पढ़ने के समय 100% सटीक जानकारी की आवश्यकता नहीं है)।
विचाराधीन कार्य एक घंटे में 1 मिलियन से अधिक डेटाबेस लेनदेन कर रहा होगा।

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

क्या किसी को इस तरह के लोड (या उच्चतर) के साथ कोई अनुभव है? क्या MyISAM जाने का रास्ता है?


13
MySQL प्रदर्शन ब्लॉग बात के इस प्रकार के लिए एक महान स्रोत है।
ceejayoz

3
यह इस पर थोड़ा निर्भर करेगा कि क्या आप सिस्टम ओएलटीपी हैं या अधिक डेटावेयरहाउस ओरिएंटेड हैं (जहां अधिकांश राइट्स बल्क लोडिंग हैं)।
ओपन स्कूल

35
MyISAM पंक्ति-लॉकिंग, लेनदेन का समर्थन नहीं करता है, यह विदेशी कुंजी का भी समर्थन नहीं करता है ... नरक, क्योंकि यह ACID प्रदान नहीं कर सकता है , यह शायद ही एक उचित डेटाबेस माना जा सकता है! यही कारण है कि InnoDB MySQL 5.5 के बाद से डिफ़ॉल्ट इंजन रहा है ... लेकिन, जो भी कारण के लिए, MyISAM PhpMyAdmin के भीतर बनाई गई तालिकाओं के लिए डिफ़ॉल्ट इंजन होना जारी है, इसलिए MyISAM पर चलने के बाद से बहुत सारे शौकिया डेटाबेस।
ब्लूराजा - डैनी पफ्लुघोटे


जवाबों:


523

मैंने इस प्रश्न पर एक तालिका में संक्षेप में चर्चा की है ताकि आप यह निष्कर्ष निकाल सकें कि क्या InnoDB या MyISAM के साथ जाना है ।

यहाँ एक छोटा सा अवलोकन है कि किस db स्टोरेज इंजन का आपको किस स्थिति में उपयोग करना चाहिए:

                                                 MyISAM InnoDB
-------------------------------------------------- --------------
आवश्यक पूर्ण-पाठ खोज हां 5.6.4
-------------------------------------------------- --------------
लेनदेन की आवश्यकता है हाँ
-------------------------------------------------- --------------
लगातार प्रश्नों का चयन करें हाँ      
-------------------------------------------------- --------------
लगातार डालें, अपडेट करें, हां हटाएं
-------------------------------------------------- --------------
रो लॉकिंग (सिंगल टेबल पर मल्टी प्रोसेसिंग) हां
-------------------------------------------------- --------------
संबंधपरक आधार डिजाइन हां

सारांश

  • लगभग सभी परिस्थितियों में, InnoDB जाने का सबसे अच्छा तरीका है
  • लेकिन, लगातार पढ़ने, लगभग कोई लेखन नहीं, MyISAM का उपयोग करें
  • MySQL में पूर्ण-पाठ खोज <= 5.5, MyISAM का उपयोग करें

11
InnoDB के पास MySQL 5.6 में पूर्ण पाठ अनुक्रमणिका है, लेकिन अभी तक, वे वास्तव में उत्पादन उपयोग के लिए तैयार नहीं हैं।
बिल कार्विन

3
12.9 पर समझौता पूर्ण-पाठ खोज कार्य , "पूर्ण-पाठ अनुक्रमणिका केवल InnoDB या MyISAM तालिकाओं के साथ उपयोग किया जा सकता है"। MySQL के लिए ठीक लगता है> = 5.6, हालांकि MySQL 5.5 के लिए एक ही पृष्ठ, फिर भी कहता है "पूर्ण-पाठ अनुक्रमित का उपयोग केवल MyISAM तालिकाओं के साथ किया जा सकता है"। ऊपर दी गई तालिका को यह कहा जा सकता है कि यह MySQL संस्करणों के साथ कैसे भिन्न है। दुर्भाग्य से, अब तक, MySQL 5.5 मानक प्रतीत होता है।
हिबौ57

2
का क्या मतलब है: InnoDB - full-text: 5.6.4?? यह हाँ या नहीं?

2
MyISAM भी आंतरिक रूप से पंक्ति की गणना करता है। इसलिए, काउंट () फ़ंक्शन MyISAM में लगभग मुफ्त है, जबकि यह InnoDB में ध्यान देने योग्य समय लेता है।
हेडेशी

3
अच्छी तालिका, लेकिन गुणवत्ता और स्थिरता के लिए एक पंक्ति जोड़कर, MyIsam = no, innoDB = हां इसे और भी बेहतर
बनाएगा

268

मैं एक डेटाबेस विशेषज्ञ नहीं हूं, और मैं अनुभव से नहीं बोलता हूं। तथापि:

MyISAM टेबल टेबल-लेवल लॉकिंग का उपयोग करते हैं । आपके ट्रैफ़िक अनुमानों के आधार पर, आपके पास प्रति सेकंड 200 लिखने के करीब है। MyISAM के साथ, इनमें से केवल किसी भी समय प्रगति हो सकती है । आपको यह सुनिश्चित करना होगा कि आपका हार्डवेयर ओवररन होने से बचने के लिए इन लेन-देन के साथ रख सकता है, अर्थात, एक भी क्वेरी 5ms से अधिक नहीं ले सकता है।

इससे मुझे पता चलता है कि आपको एक भंडारण इंजन की आवश्यकता होगी जो पंक्ति-स्तरीय लॉकिंग का समर्थन करता है, अर्थात, InnoDB।

दूसरी ओर, प्रत्येक भंडारण इंजन के साथ लोड का अनुकरण करने के लिए कुछ सरल स्क्रिप्ट लिखने के लिए काफी तुच्छ होना चाहिए, फिर परिणामों की तुलना करें।


12
200 के करीब? यदि उसका औसत लेन-देन 2.5 प्रश्न करता है, तो यह है कि [(2.5 * 1M) / 3600s =] 700 के करीब।
Ozzy

12
मैं इस बात से भी असहमत हूं a single query can take no more than 5msक्योंकि आपने 2 संभावना नहीं बनाई; A: सभी प्रश्नों के लिए एक ही तालिका की आवश्यकता थी और B: केवल 1 कनेक्शन उपलब्ध था! मुझे आपको सूचित करना चाहिए कि उच्च रैम के साथ एक लिनक्स और MySQL 5.5 सेट-अप के साथ 10,000 से अधिक कनेक्शन का समर्थन कर सकता है (देखें: dev.mysql.com/doc/refman//5.5/en/too-many-connections.html )
ओजेजी

152
जब एक टेबल टेबल लॉक की जाती है, तो एक बार में एक ही क्वेरी उसके खिलाफ चल सकती है। इससे कोई फर्क नहीं पड़ता कि सर्वर 10000 एक साथ कनेक्शन का समर्थन करता है, जबकि टेबल लॉक होने पर प्रत्येक बैक अप करेगा।
रायनर

2
इसके अलावा यह जानना उपयोगी हो सकता है कि माईएसएएम स्थानिक सूचकांक का समर्थन करता है जबकि इनोबीडी नहीं करता है। और MyISAM विदेशी कुंजियों का उपयोग नहीं करता है भले ही यह एक बनाने से रोकता नहीं है।
क्रिया

4
@kriver: आपके पास MyISAM तालिकाओं में विदेशी कुंजी नहीं हो सकती। आप FATE परिभाषाओं को CREATE TABLE कथनों में शामिल कर सकते हैं लेकिन उन्हें (परिभाषाओं को) नजरअंदाज कर दिया जाता है।
ypercube y

191

लोग अक्सर प्रदर्शन के बारे में बात करते हैं, बनाम लिखते हैं, विदेशी कुंजी लिखते हैं, लेकिन मेरी राय में एक भंडारण इंजन के लिए एक और सुविधा होनी चाहिए: परमाणु अपडेट।

इसे इस्तेमाल करे:

  1. 5 मिनट लगते हैं अपने MyISAM तालिका के खिलाफ एक अद्यतन जारी करें।
  2. जब UPDATE प्रगति पर है, तो 2.5 सेकंड में, इसे बाधित करने के लिए Ctrl-C दबाएं।
  3. मेज पर प्रभाव का निरीक्षण करें। कितनी पंक्तियों को अपडेट किया गया था? कितने अपडेट नहीं हुए? क्या तालिका भी पठनीय है, या जब आप Ctrl-C से टकराए थे, तो क्या यह दूषित था?
  4. एक InnoDB तालिका के खिलाफ अद्यतन के साथ एक ही प्रयोग करने की कोशिश करें, प्रगति में क्वेरी को बाधित।
  5. InnoDB तालिका देखें। शून्य पंक्तियों को अपडेट किया गया था। InnoDB ने आश्वासन दिया है कि आपके पास परमाणु अद्यतन हैं, और यदि पूर्ण अद्यतन नहीं किया जा सकता है, तो यह संपूर्ण परिवर्तन को वापस करता है। इसके अलावा, तालिका भ्रष्ट नहीं है। यदि आप killall -9 mysqldकिसी दुर्घटना का अनुकरण करने के लिए उपयोग करते हैं तो भी यह काम करता है ।

प्रदर्शन निश्चित रूप से वांछनीय है, लेकिन डेटा नहीं खोना चाहिए।


4
रिकॉर्ड के लिए, ACID डेटाबेस की अन्य विशेषताओं - संगति, अलगाव और स्थायित्व - म्यांमार द्वारा समर्थित नहीं हैं।
बिल कार्विन

नियंत्रण-सी को तालिका को भ्रष्ट नहीं करना चाहिए - क्योंकि चेक टेबल में सफलता वापस आ जाएगी और सभी प्रश्न बिना त्रुटियों के आगे बढ़ेंगे। MyISAM सभी रिकॉर्ड्स को अपडेट किए बिना अपडेट को रद्द कर देगा, लेकिन टेबल आंतरिक संरचनात्मक अखंडता बनाए रखेगा। SIGTERM के साथ mysqld को मारने का समान प्रभाव पड़ेगा। हालाँकि यदि आप इसे SIGKILL (किल -9) या कुछ क्रैशिंग सिग्नल देते हैं (या यह अपने आप ही इसे कमाता है जब यह बग मारता है), या यदि OS क्रैश / पावर खो जाता है, तो यह एक अलग कहानी है - आप देख सकते हैं MyISAM- स्तर का भ्रष्टाचार।
साशा पचेव

1
InnoDB अपने आप को रोयली के रूप में अच्छी तरह से भ्रष्ट कर सकता है, आमतौर पर MyISAM की तुलना में अधिक रोयली जब यह करता है। एसीआईडी ​​की विडंबना यह है कि हमारे पास सभी या कुछ नहीं की धारणा है। इसलिए जब InnoDB सभी नहीं दे सकता है, यह कुछ भी नहीं देता है - आंतरिक मुखर, और यह बिल्कुल भी चलाने से इनकार करता है क्योंकि किसी संरचना में एक बाइट गलत है - 90% समय इसे नजरअंदाज किया जा सकता था और यह केवल एक तालिका को प्रभावित करेगा। हाल के पर्कोना सर्वर के पास इससे निपटने का विकल्प है - innodb_pass_corrupt_table।
साशा पचेव

1
मैं पिछले 3 दिनों से इस तरह की जानकारी खोज रहा था, अब मुझे यह मिल गया है। InnoDB सबसे अच्छा है। धन्यवादBill Karwin
user3833682

3
@ flow2k, इन दिनों लगभग कोई नहीं। मेरी पिछली नौकरी में हमने एक सर्वर पर एक तालिका के लिए MyISAM का उपयोग किया था, और एकमात्र कारण यह था कि MyISAM उस विशिष्ट तालिका को InnoDB से कम स्थान पर संग्रहीत करने में सक्षम था। हम डिस्क स्थान पर विवश थे, इसलिए हमें MyISAM का उपयोग करना था जब तक कि हम डेटाबेस को दूसरे सर्वर पर नहीं ले जा सकते। मेरी नई नौकरी में, पहले से ही एक नीति है कि हर टेबल में InnoDB होना चाहिए।
बिल करविन

138

मैंने MySQL का उपयोग करते हुए एक उच्च-वॉल्यूम सिस्टम पर काम किया है और मैंने MyISAM और InnoDB दोनों की कोशिश की है।

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

अंत में मैंने डेटा को टुकड़े करके विवाद मुद्दे को हल किया जैसे कि आवेषण एक "गर्म" तालिका में चला गया और चयनों ने कभी भी गर्म तालिका को परेशान नहीं किया।

इसने डिलीट की अनुमति दी (डेटा समय के प्रति संवेदनशील था और हमने केवल "स्थिर" तालिकाओं पर होने के लिए एक्स दिनों को बनाए रखा था) जो फिर से चुनिंदा प्रश्नों द्वारा छुआ नहीं गया था। लगता है कि InnoDB बल्क डिलीट पर खराब प्रदर्शन करता है, इसलिए यदि आप डेटा को शुद्ध करने की योजना बना रहे हैं, तो आप इसे इस तरह से संरचित करना चाह सकते हैं कि पुराना डेटा एक बासी मेज में हो, जो उस पर डिलीट चलाने के बजाय बस गिरा दिया जा सकता है।

बेशक, मुझे पता नहीं है कि आपका आवेदन क्या है, लेकिन उम्मीद है कि यह आपको कुछ मुद्दों में MyISAM और InnoDB के साथ कुछ अंतर्दृष्टि देता है।


3
'अंत में मैं डेटा fragmenting ऐसी है कि आवेषण एक "गर्म" तालिका में चला गया और चयन गर्म तालिका पूछे कभी नहीं से विवाद समस्या हल हो गई। " - नहीं है कि एक क्या अनिवार्य रूप से है बफर पूल ? के लिए है
BlueRaja - डैनी Pflughoeft

15
डैनी - नहीं, सच में नहीं। ट्यूनिंग सर्वर सेटिंग्स महत्वपूर्ण है, लेकिन किसी भी तरह से आपके स्कीमा के विचारशील संरचना के लिए एक विकल्प नहीं है। यदि आपके पास DB बहुत है, उपलब्ध RAM और एक्सेस पैटर्न की तुलना में बहुत बड़ा है जो डेटा को सभी DB में बेतरतीब ढंग से छूता है तो दुनिया के सभी बफर पूल आपको मदद नहीं करेंगे। यदि आप डेटा और एक्सेस पैटर्न को समझते हैं तो आप सावधान डिज़ाइन के माध्यम से दर्द को कम कर सकते हैं।
अलंक १०

66

खेल में थोड़ा देर हो गई ... लेकिन यहाँ एक व्यापक पोस्ट मैंने कुछ महीने पहले लिखी थी , जिसमें MYISAM और InnoDB के बीच के प्रमुख अंतरों का वर्णन किया गया था। एक क्यूपा (और शायद एक बिस्किट) पकड़ो, और आनंद लो।


MyISAM और InnoDB के बीच मुख्य अंतर संदर्भात्मक अखंडता और लेनदेन में है। अन्य अंतर भी हैं जैसे कि लॉकिंग, रोलबैक और पूर्ण-पाठ खोजें।

निर्देशात्मक अखंडता

प्रासंगिक अखंडता सुनिश्चित करती है कि तालिकाओं के बीच संबंध सुसंगत रहे। अधिक विशेष रूप से, इसका मतलब है जब एक तालिका (जैसे लिस्टिंग) में एक विदेशी कुंजी (जैसे उत्पाद आईडी) होती है, जो एक अलग तालिका (जैसे उत्पाद) की ओर इशारा करती है, जब इंगित या तालिका में अद्यतन या हटाए जाते हैं, तो ये परिवर्तन लिंकिंग के लिए कैस्केड किए जाते हैं तालिका। हमारे उदाहरण में, यदि किसी उत्पाद का नाम बदला गया है, तो लिंकिंग टेबल की विदेशी कुंजियाँ भी अपडेट होंगी; यदि किसी उत्पाद को 'उत्पाद' तालिका से हटा दिया जाता है, तो कोई प्रविष्टि जो हटाए गए प्रविष्टि को इंगित करती है, भी हटा दी जाएगी। इसके अलावा, किसी भी नई सूची में एक वैध, मौजूदा प्रविष्टि की ओर इशारा करने वाली विदेशी कुंजी होनी चाहिए।

InnoDB एक संबंधपरक DBMS (RDBMS) है और इस प्रकार इसमें संदर्भात्मक अखंडता है, जबकि MyISAM नहीं है।

लेन-देन और परमाणु

तालिका में डेटा का चयन डेटा मैनिपुलेशन लैंग्वेज (डीएमएल) स्टेटमेंट्स जैसे कि SELECT, INSERT, UPDATE और DELETE का उपयोग करके किया जाता है। एक लेनदेन समूह दो या दो से अधिक डीएमएल एक साथ काम की एक इकाई में बयान करता है, इसलिए या तो पूरी इकाई को लागू किया जाता है, या इसमें से कोई भी नहीं है।

MyISAM लेनदेन का समर्थन नहीं करता है जबकि InnoDB करता है।

यदि किसी ऑपरेशन को MyISAM तालिका का उपयोग करते समय बाधित किया जाता है, तो ऑपरेशन को तुरंत समाप्त कर दिया जाता है, और जो पंक्तियाँ (या प्रत्येक पंक्ति के भीतर डेटा) प्रभावित होती हैं वे प्रभावित बनी रहती हैं, भले ही ऑपरेशन पूरा होने पर नहीं गया हो।

यदि एक InnoDB तालिका का उपयोग करते समय एक ऑपरेशन बाधित होता है, क्योंकि यह लेनदेन का उपयोग करता है, जिसमें परमाणुता है, कोई भी लेनदेन जो पूरा नहीं हुआ, वह प्रभावी नहीं होगा, क्योंकि कोई प्रतिबद्ध नहीं है।

टेबल-लॉकिंग बनाम रो-लॉकिंग

जब कोई क्वेरी MyISAM तालिका के विरुद्ध चलती है, तो जिस तालिका में वह क्वेरी कर रहा है, वह पूरी लॉक हो जाएगी। इसका मतलब है कि बाद के प्रश्नों को केवल एक चालू होने के बाद निष्पादित किया जाएगा। यदि आप एक बड़ी तालिका पढ़ रहे हैं, और / या लगातार पढ़ने और लिखने के काम कर रहे हैं, तो इसका मतलब प्रश्नों का एक विशाल बैकलॉग हो सकता है।

जब एक InnoDB तालिका के खिलाफ एक क्वेरी चलती है, केवल पंक्ति (s) जो शामिल हैं, लॉक हो जाती हैं, तो बाकी तालिका CRUD संचालन के लिए उपलब्ध रहती है। इसका मतलब है कि क्वेरी एक ही टेबल पर एक साथ चल सकती हैं, बशर्ते वे एक ही पंक्ति का उपयोग न करें।

InnoDB में इस सुविधा को संगामिति के रूप में जाना जाता है। समसामयिक के रूप में महान के रूप में, वहाँ एक बड़ी खामी है कि तालिकाओं की एक चुनिंदा सीमा पर लागू होता है, उस में कर्नेल थ्रेड्स के बीच स्विच करने में एक ओवरहेड है, और सर्वर को रोकने के लिए आने से रोकने के लिए आपको कर्नेल थ्रेड्स पर एक सीमा निर्धारित करनी चाहिए। ।

लेन-देन और रोलबैक

जब आप MyISAM में एक ऑपरेशन चलाते हैं, तो परिवर्तन निर्धारित किए जाते हैं; InnoDB में, उन परिवर्तनों को वापस लाया जा सकता है। लेन-देन को नियंत्रित करने के लिए उपयोग किए जाने वाले सबसे सामान्य आदेश COMMIT, ROLLBACK और SAVEPOINT हैं। 1. कमिट - आप कई डीएमएल संचालन लिख सकते हैं, लेकिन परिवर्तन केवल तभी किया जाएगा जब एक कमिट बनाया जाता है। 2. रोलबैक - आप अभी तक अभी तक प्रतिबद्ध नहीं किए गए किसी भी संचालन को त्याग सकते हैं। 3. बचत - की सूची में एक बिंदु सेट करता है ऑपरेशन जिसके लिए एक रोलबैक ऑपरेशन को रोलबैक किया जा सकता है

विश्वसनीयता

MyISAM कोई डेटा अखंडता प्रदान नहीं करता है - हार्डवेयर विफलताओं, अशुद्ध शटडाउन और रद्द किए गए संचालन के कारण डेटा दूषित हो सकता है। इसके लिए अनुक्रमणिका और तालिकाओं की पूर्ण मरम्मत या पुनर्निर्माण की आवश्यकता होगी।

दूसरी ओर, InnoDB, भ्रष्टाचार को रोकने के लिए एक ट्रांजेक्शनल लॉग, एक डबल-राइट बफर और स्वचालित चेकसमिंग और सत्यापन का उपयोग करता है। इससे पहले कि InnoDB कोई बदलाव करता है, यह ibdata1 नामक एक सिस्टम टेबलस्पेस फ़ाइल में लेनदेन से पहले डेटा रिकॉर्ड करता है। यदि कोई दुर्घटना होती है, तो इन लॉग्स के रिप्ले के माध्यम से इनोबीडी ऑटोरोवर होगा।

पूर्ण अनुक्रमण

InnoDB MySQL संस्करण 5.6.4 तक FULLTEXT अनुक्रमण का समर्थन नहीं करता है। इस पोस्ट के लेखन के रूप में, कई साझा होस्टिंग प्रदाता 'MySQL संस्करण अभी भी 5.6.4 से नीचे है, जिसका अर्थ है कि FULLTEXT इंडेक्सिंग InnoDB तालिकाओं के लिए समर्थित नहीं है।

हालाँकि, यह MyISAM का उपयोग करने के लिए एक वैध कारण नहीं है। यह एक होस्टिंग प्रदाता में बदलने के लिए सबसे अच्छा है जो MySQL के अद्यतित संस्करणों का समर्थन करता है। ऐसा नहीं है कि एक FISTEXT अनुक्रमणिका का उपयोग करने वाली MyISAM तालिका को एक InnoDB तालिका में परिवर्तित नहीं किया जा सकता है।

निष्कर्ष

अंत में, InnoDB पसंद का आपका डिफ़ॉल्ट भंडारण इंजन होना चाहिए। जब वे विशिष्ट आवश्यकता की पूर्ति करते हैं तो MyISAM या अन्य डेटा प्रकार चुनें।


मैं एक php सत्र चेकसम स्क्रिप्ट बना रहा था और मेरी अधिकांश कुंजी [az09] के यादृच्छिक तार हैं ... Innodb ने 30ms से अधिक का समय लिया INSERT ON DUPLICATE KEY UPDATEइसलिए मैंने MyISAM की कोशिश की और अब यह नीचे <1ms है ... कई उत्तर मैंने देखा कि innodb के पास 'असंगत' (यादृच्छिक स्ट्रिंग) अद्वितीय कुंजियों से निपटने का कठिन समय है ... क्या आपके पास उस पर हमारे लिए कोई इनपुट है? वास्तव में मैं यह सोच रहा था कि इस पर MyISAM का क्या असर पड़ेगा लेकिन आपके शानदार जवाब ने मुझे एहसास दिलाया कि यह इस विशेष मामले के लिए रास्ता है।
लुई लाउडोग ट्रॉटियर

64

अधिक लिखने और पढ़ने के साथ एक लोड के लिए, आपको InnoDB से लाभ होगा। क्योंकि InnoDB टेबल-लॉकिंग के बजाय रो-लॉकिंग प्रदान करता है, आपका SELECTएस समवर्ती हो सकता है, न केवल एक दूसरे के साथ, बल्कि कई INSERTएस के साथ । हालाँकि, जब तक आप SQL लेनदेन का उपयोग करने का इरादा नहीं रखते हैं, तब तक InnoDB कमिट फ्लश 2 ( innodb_flush_log_at_trx_commit ) पर सेट करें । यह आपको बहुत सारे कच्चे प्रदर्शन वापस देता है जो आप अन्यथा MyISAM से InnoDB तक तालिकाओं को स्थानांतरित करते समय खो देंगे।

इसके अलावा, प्रतिकृति जोड़ने पर विचार करें। यह आपको कुछ रीड स्केलिंग देता है और जब से आपने कहा था कि आपके रीड को अप-टू-डेट नहीं होना है, आप प्रतिकृति को थोड़ा पीछे छोड़ सकते हैं। बस यह सुनिश्चित करें कि यह किसी भी चीज़ के नीचे से पकड़ सकता है लेकिन सबसे भारी ट्रैफ़िक या यह हमेशा पीछे रहेगा और कभी नहीं पकड़ेगा। आप इस तरह से जाना अगर, हालांकि, मैं दृढ़ता से आप अपने डेटाबेस हैंडलर के दास और प्रतिकृति अंतराल प्रबंधन से पढ़ने को अलग सलाह देते हैं। यह इतना सरल है यदि एप्लिकेशन कोड को इस बारे में पता नहीं है।

अंत में, अलग-अलग टेबल लोड के बारे में पता होना चाहिए। आपके पास सभी तालिकाओं पर समान पढ़ने / लिखने का अनुपात नहीं होगा। लगभग 100% रीड्स के साथ कुछ छोटे टेबल MyISAM रहने का जोखिम उठा सकते हैं। इसी तरह, यदि आपके पास कुछ टेबल हैं, जो 100% लिखने के पास हैं, तो आपको इससे लाभ हो सकता है INSERT DELAYED, लेकिन यह केवल MyISAM में समर्थित है ( DELAYEDएक InnoDB तालिका के लिए खंड को अनदेखा किया गया है)।

लेकिन यह सुनिश्चित करने के लिए बेंचमार्क।


4
"InnoDB प्रतिबद्ध फ्लश" क्या आप को देखें innodb_flush_log_at_trx_commit?
सिजयोज़

2
मुझे आपकी पोस्ट बहुत उपयोगी लगी - धन्यवाद। वर्तमान में मेरी तालिका और आपकी पोस्ट के लिए MyISAM / InnoDB का उपयोग करते समय मूल्यांकन करना सहायक था। चीयर्स।
starmonkey

2
dev.mysql.com/doc/refman/5.5/en/insert-delayed.html स्टेट्स: MyISAM तालिकाओं के लिए, यदि डेटा फ़ाइल के बीच में कोई खाली ब्लॉक नहीं हैं, तो समवर्ती चयन और INSERT कथन समर्थित हैं। इन परिस्थितियों में, आपको शायद ही कभी MyISAM के साथ INSERT DELAYED का उपयोग करने की आवश्यकता हो।
tymtam

बहुत जानकारीपूर्ण पोस्ट। मेरे पास ऑप्स के समान ही प्रश्न था और मुझे यह कहना है कि आपके पोस्ट ने मुझे मेरे डेटाबेस इंजन निर्णय के बारे में आसानी से बता दिया है। धन्यवाद! ++
जो मेजेस्की

त्वरित टिप्पणी: विलंबित अब 5.7 में समर्थित नहीं है। आप इसके बजाय LOW_PRIORITY के साथ परीक्षण करना चाह सकते हैं।
वेबमैट

59

दो इंजनों के बीच यांत्रिक अंतरों को कवर करते हुए यहां प्रतिक्रियाओं के व्यापक चयन को जोड़ने के लिए, मैं एक अनुभवजन्य गति तुलना अध्ययन प्रस्तुत करता हूं।

शुद्ध गति के संदर्भ में, यह हमेशा ऐसा नहीं होता है कि MyISAM InnoDB से अधिक तेज़ है, लेकिन मेरे अनुभव में यह लगभग 2.0-2.5 गुना के कारक द्वारा PURE READ काम करने के वातावरण के लिए तेज़ हो जाता है। स्पष्ट रूप से यह सभी वातावरणों के लिए उपयुक्त नहीं है - जैसा कि अन्य ने लिखा है, MyISAM में लेनदेन और विदेशी कुंजी जैसी चीजों का अभाव है।

मैंने नीचे थोड़ा सा बेंचमार्किंग किया है - मैंने लूपिंग के लिए अजगर और टाइमिंग की तुलना के लिए टाइमिट लाइब्रेरी का उपयोग किया है। रुचि के लिए मैंने मेमोरी इंजन को भी शामिल किया है, यह बोर्ड भर में सबसे अच्छा प्रदर्शन देता है, हालांकि यह केवल छोटी तालिकाओं के लिए उपयुक्त है ( The table 'tbl' is fullजब आप MySQL मेमोरी सीमा से अधिक हो जाते हैं तो लगातार मुठभेड़ )। मेरे द्वारा देखे जाने वाले चार प्रकार हैं:

  1. वेनिला का चयन करता है
  2. मायने रखता है
  3. सशर्त चयन
  4. अनुक्रमित और गैर-अनुक्रमित उप-चयन

सबसे पहले, मैंने निम्न एसक्यूएल का उपयोग करके तीन तालिकाओं का निर्माण किया

CREATE TABLE
    data_interrogation.test_table_myisam
    (
        index_col BIGINT NOT NULL AUTO_INCREMENT,
        value1 DOUBLE,
        value2 DOUBLE,
        value3 DOUBLE,
        value4 DOUBLE,
        PRIMARY KEY (index_col)
    )
    ENGINE=MyISAM DEFAULT CHARSET=utf8

'MyISAM' के साथ दूसरे और तीसरे टेबल में 'InnoDB' और 'मेमोरी' के लिए प्रतिस्थापित।

 

1) वेनिला का चयन करता है

प्रश्न: SELECT * FROM tbl WHERE index_col = xx

परिणाम: ड्रा

वेनिला की तुलना विभिन्न डेटाबेस इंजनों द्वारा की जाती है

इनमें से सभी की गति समान रूप से समान है, और अपेक्षा के अनुसार चयनित होने वाले कॉलम की संख्या में रैखिक है। InnoDB MyISAM की तुलना में थोड़ा तेज़ लगता है लेकिन यह वास्तव में मामूली है।

कोड:

import timeit
import MySQLdb
import MySQLdb.cursors
import random
from random import randint

db = MySQLdb.connect(host="...", user="...", passwd="...", db="...", cursorclass=MySQLdb.cursors.DictCursor)
cur = db.cursor()

lengthOfTable = 100000

# Fill up the tables with random data
for x in xrange(lengthOfTable):
    rand1 = random.random()
    rand2 = random.random()
    rand3 = random.random()
    rand4 = random.random()

    insertString = "INSERT INTO test_table_innodb (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"
    insertString2 = "INSERT INTO test_table_myisam (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"
    insertString3 = "INSERT INTO test_table_memory (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"

    cur.execute(insertString)
    cur.execute(insertString2)
    cur.execute(insertString3)

db.commit()

# Define a function to pull a certain number of records from these tables
def selectRandomRecords(testTable,numberOfRecords):

    for x in xrange(numberOfRecords):
        rand1 = randint(0,lengthOfTable)

        selectString = "SELECT * FROM " + testTable + " WHERE index_col = " + str(rand1)
        cur.execute(selectString)

setupString = "from __main__ import selectRandomRecords"

# Test time taken using timeit
myisam_times = []
innodb_times = []
memory_times = []

for theLength in [3,10,30,100,300,1000,3000,10000]:

    innodb_times.append( timeit.timeit('selectRandomRecords("test_table_innodb",' + str(theLength) + ')', number=100, setup=setupString) )
    myisam_times.append( timeit.timeit('selectRandomRecords("test_table_myisam",' + str(theLength) + ')', number=100, setup=setupString) )
    memory_times.append( timeit.timeit('selectRandomRecords("test_table_memory",' + str(theLength) + ')', number=100, setup=setupString) )

 

2) मायने रखता है

प्रश्न: SELECT count(*) FROM tbl

परिणाम: MyISAM जीतता है

विभिन्न डेटाबेस इंजनों द्वारा गणना की तुलना

यह एक MyISAM और InnoDB के बीच एक बड़ा अंतर प्रदर्शित करता है - MyISAM (और मेमोरी) तालिका में रिकॉर्ड की संख्या पर नज़र रखता है, इसलिए यह लेनदेन तेज़ है और O (1) है। इनोबीडीबी को गिनने के लिए आवश्यक समय की मात्रा उस श्रेणी में तालिका आकार के साथ सुपर-रैखिक रूप से बढ़ जाती है जिसकी मैंने जांच की थी। मुझे संदेह है कि व्यवहार में देखे गए MyISAM प्रश्नों में से कई स्पीड-अप समान प्रभावों के कारण हैं।

कोड:

myisam_times = []
innodb_times = []
memory_times = []

# Define a function to count the records
def countRecords(testTable):

    selectString = "SELECT count(*) FROM " + testTable
    cur.execute(selectString)

setupString = "from __main__ import countRecords"

# Truncate the tables and re-fill with a set amount of data
for theLength in [3,10,30,100,300,1000,3000,10000,30000,100000]:

    truncateString = "TRUNCATE test_table_innodb"
    truncateString2 = "TRUNCATE test_table_myisam"
    truncateString3 = "TRUNCATE test_table_memory"

    cur.execute(truncateString)
    cur.execute(truncateString2)
    cur.execute(truncateString3)

    for x in xrange(theLength):
        rand1 = random.random()
        rand2 = random.random()
        rand3 = random.random()
        rand4 = random.random()

        insertString = "INSERT INTO test_table_innodb (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"
        insertString2 = "INSERT INTO test_table_myisam (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"
        insertString3 = "INSERT INTO test_table_memory (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"

        cur.execute(insertString)
        cur.execute(insertString2)
        cur.execute(insertString3)

    db.commit()

    # Count and time the query
    innodb_times.append( timeit.timeit('countRecords("test_table_innodb")', number=100, setup=setupString) )
    myisam_times.append( timeit.timeit('countRecords("test_table_myisam")', number=100, setup=setupString) )
    memory_times.append( timeit.timeit('countRecords("test_table_memory")', number=100, setup=setupString) )

 

3) सशर्त चयन करता है

प्रश्न: SELECT * FROM tbl WHERE value1<0.5 AND value2<0.5 AND value3<0.5 AND value4<0.5

परिणाम: MyISAM जीतता है

विभिन्न डेटाबेस इंजनों द्वारा सशर्त चयनों की तुलना

यहाँ, MyISAM और मेमोरी लगभग समान हैं, और बड़ी तालिकाओं के लिए InnoDB को लगभग 50% तक हरा देते हैं। यह क्वेरी का प्रकार है जिसके लिए MyISAM का लाभ अधिकतम प्रतीत होता है।

कोड:

myisam_times = []
innodb_times = []
memory_times = []

# Define a function to perform conditional selects
def conditionalSelect(testTable):
    selectString = "SELECT * FROM " + testTable + " WHERE value1 < 0.5 AND value2 < 0.5 AND value3 < 0.5 AND value4 < 0.5"
    cur.execute(selectString)

setupString = "from __main__ import conditionalSelect"

# Truncate the tables and re-fill with a set amount of data
for theLength in [3,10,30,100,300,1000,3000,10000,30000,100000]:

    truncateString = "TRUNCATE test_table_innodb"
    truncateString2 = "TRUNCATE test_table_myisam"
    truncateString3 = "TRUNCATE test_table_memory"

    cur.execute(truncateString)
    cur.execute(truncateString2)
    cur.execute(truncateString3)

    for x in xrange(theLength):
        rand1 = random.random()
        rand2 = random.random()
        rand3 = random.random()
        rand4 = random.random()

        insertString = "INSERT INTO test_table_innodb (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"
        insertString2 = "INSERT INTO test_table_myisam (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"
        insertString3 = "INSERT INTO test_table_memory (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"

        cur.execute(insertString)
        cur.execute(insertString2)
        cur.execute(insertString3)

    db.commit()

    # Count and time the query
    innodb_times.append( timeit.timeit('conditionalSelect("test_table_innodb")', number=100, setup=setupString) )
    myisam_times.append( timeit.timeit('conditionalSelect("test_table_myisam")', number=100, setup=setupString) )
    memory_times.append( timeit.timeit('conditionalSelect("test_table_memory")', number=100, setup=setupString) )

 

4) उप-चयन

परिणाम: InnoDB जीतता है

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

CREATE TABLE
    subselect_myisam
    (
        index_col bigint NOT NULL,
        non_index_col bigint,
        PRIMARY KEY (index_col)
    )
    ENGINE=MyISAM DEFAULT CHARSET=utf8;

जहाँ एक बार फिर, दूसरी तालिका में 'MyISAM' को 'InnoDB' के लिए प्रतिस्थापित किया गया है।

इस क्वेरी में, मैं चयन तालिका का आकार 1000000 पर छोड़ता हूं और इसके बजाय उप-चयनित कॉलम के आकार को बदलता हूं।

विभिन्न डेटाबेस इंजनों द्वारा उप-चयनों की तुलना

यहां इनोबीडी आसानी से जीत जाता है। जब हम एक उचित आकार की मेज पर जाते हैं, तो दोनों इंजन उप-चयन के आकार के साथ रैखिक रूप से मापते हैं। सूचकांक MyISAM कमांड को गति देता है लेकिन इनोबीडी की गति पर दिलचस्प प्रभाव पड़ता है। subSelect.png

कोड:

myisam_times = []
innodb_times = []
myisam_times_2 = []
innodb_times_2 = []

def subSelectRecordsIndexed(testTable,testSubSelect):
    selectString = "SELECT * FROM " + testTable + " WHERE index_col in ( SELECT index_col FROM " + testSubSelect + " )"
    cur.execute(selectString)

setupString = "from __main__ import subSelectRecordsIndexed"

def subSelectRecordsNotIndexed(testTable,testSubSelect):
    selectString = "SELECT * FROM " + testTable + " WHERE index_col in ( SELECT non_index_col FROM " + testSubSelect + " )"
    cur.execute(selectString)

setupString2 = "from __main__ import subSelectRecordsNotIndexed"

# Truncate the old tables, and re-fill with 1000000 records
truncateString = "TRUNCATE test_table_innodb"
truncateString2 = "TRUNCATE test_table_myisam"

cur.execute(truncateString)
cur.execute(truncateString2)

lengthOfTable = 1000000

# Fill up the tables with random data
for x in xrange(lengthOfTable):
    rand1 = random.random()
    rand2 = random.random()
    rand3 = random.random()
    rand4 = random.random()

    insertString = "INSERT INTO test_table_innodb (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"
    insertString2 = "INSERT INTO test_table_myisam (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"

    cur.execute(insertString)
    cur.execute(insertString2)

for theLength in [3,10,30,100,300,1000,3000,10000,30000,100000]:

    truncateString = "TRUNCATE subselect_innodb"
    truncateString2 = "TRUNCATE subselect_myisam"

    cur.execute(truncateString)
    cur.execute(truncateString2)

    # For each length, empty the table and re-fill it with random data
    rand_sample = sorted(random.sample(xrange(lengthOfTable), theLength))
    rand_sample_2 = random.sample(xrange(lengthOfTable), theLength)

    for (the_value_1,the_value_2) in zip(rand_sample,rand_sample_2):
        insertString = "INSERT INTO subselect_innodb (index_col,non_index_col) VALUES (" + str(the_value_1) + "," + str(the_value_2) + ")"
        insertString2 = "INSERT INTO subselect_myisam (index_col,non_index_col) VALUES (" + str(the_value_1) + "," + str(the_value_2) + ")"

        cur.execute(insertString)
        cur.execute(insertString2)

    db.commit()

    # Finally, time the queries
    innodb_times.append( timeit.timeit('subSelectRecordsIndexed("test_table_innodb","subselect_innodb")', number=100, setup=setupString) )
    myisam_times.append( timeit.timeit('subSelectRecordsIndexed("test_table_myisam","subselect_myisam")', number=100, setup=setupString) )

    innodb_times_2.append( timeit.timeit('subSelectRecordsNotIndexed("test_table_innodb","subselect_innodb")', number=100, setup=setupString2) )
    myisam_times_2.append( timeit.timeit('subSelectRecordsNotIndexed("test_table_myisam","subselect_myisam")', number=100, setup=setupString2) )

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


1
प्रदर्शन हमेशा केवल विचार नहीं है, स्थिरता के बारे में एक ग्राफ के बारे में कैसे? एक इंजन किसी भी चीज के लिए अच्छा नहीं है अगर वह क्रैश हो जाता है और बुनियादी डेटाबेस सुविधाओं का समर्थन नहीं करता है।
पिलावदज़ाइस

1
यदि my.cnfफ़ाइल InnoDB के लिए अनुकूलित नहीं है , तो MyISAM शायद ज्यादातर बार InnoDB को हरा देगा । आपने उल्लेख नहीं किया है कि आपकी my.cnfफ़ाइल कैसी दिखती है, जो वास्तव में InnoDB प्रदर्शन का सबसे महत्वपूर्ण कारक है।
इतोक्टोपस

धन्यवाद itoctopus - मुझे आपके द्वारा सुझाए गए किसी भी अनुकूलन के बारे में अधिक सुनना अच्छा लगेगा। इन परीक्षणों में उपयोग किया गया पूर्ण कोड ऊपर है, विभिन्न आशाओं के साथ प्रयोगों को दोहराने के लिए स्वतंत्र महसूस करें और हमें बताएं कि क्या आपको परिणामों में महत्वपूर्ण परिवर्तन मिलते हैं
स्टैक जी

32

थोड़ा ऑफ-टॉपिक, लेकिन प्रलेखन उद्देश्यों और पूर्णता के लिए, मैं निम्नलिखित जोड़ना चाहूंगा।

आम तौर पर InnoDB का उपयोग करने से बहुत कम जटिल अनुप्रयोग का परिणाम होगा, शायद अधिक बग-मुक्त भी। चूँकि आप सभी संदर्भात्मक अखंडता (विदेशी की-बाधाओं) को डेटामॉडल में डाल सकते हैं, आपको कहीं भी आवेदन कोड की उतनी आवश्यकता नहीं है जितनी आपको MyISAM की आवश्यकता होगी।

हर बार जब आप रिकॉर्ड दर्ज करते हैं, हटाते हैं या प्रतिस्थापित करते हैं, तो आप रिश्तों की जांच और रखरखाव करेंगे। उदाहरण के लिए, यदि आप माता-पिता को हटाते हैं, तो सभी बच्चों को भी हटा दिया जाना चाहिए। उदाहरण के लिए, यहां तक ​​कि एक साधारण ब्लॉगिंग सिस्टम में, यदि आप एक ब्लॉगपोस्टिंग रिकॉर्ड को हटाते हैं, तो आपको टिप्पणी रिकॉर्ड, पसंद आदि को हटाना होगा। InnoDB में यह स्वचालित रूप से डेटाबेस इंजन द्वारा किया जाता है (यदि आपने मॉडल में विरोधाभास निर्दिष्ट किया है) ) और कोई आवेदन कोड की आवश्यकता है। MyISAM में इसे एप्लिकेशन में कोडित करना होगा, जो वेब-सर्वर में बहुत मुश्किल है। वेब-सर्वर स्वभाव से बहुत समवर्ती / समानांतर हैं और क्योंकि ये क्रियाएं परमाणु होनी चाहिए और MyISAM कोई वास्तविक लेनदेन का समर्थन नहीं करता है, वेब-सर्वर के लिए MyISAM का उपयोग करना जोखिम भरा / त्रुटि-प्रवण है।

अधिकांश सामान्य मामलों में, कई कारणों से, इनोबीडी बहुत बेहतर प्रदर्शन करेंगे, उनमें से एक तालिका-स्तर लॉकिंग के विपरीत रिकॉर्ड स्तर लॉकिंग का उपयोग करने में सक्षम है। न केवल ऐसी स्थिति में, जहां लिखने की तुलना में अधिक बार लिखा जाता है, बड़े डेटासेट पर जटिल जोड़ के साथ स्थितियों में भी। हमने देखा कि बहुत बड़े जॉइन (कई मिनट लगते हुए) के लिए MyISAM टेबलों पर InnoDB तालिकाओं का उपयोग करके 3 गुना प्रदर्शन वृद्धि हुई है।

मैं कहूंगा कि MySQL का उपयोग करते समय सामान्य InnoDB में (संदर्भात्मक अखंडता के साथ 3NF डेटामोडेल का उपयोग करके) डिफ़ॉल्ट विकल्प होना चाहिए। MyISAM का उपयोग केवल बहुत विशिष्ट मामलों में किया जाना चाहिए। यह सबसे कम संभावना है, एक बड़ा और अधिक छोटी गाड़ी के परिणामस्वरूप परिणाम होगा।

यह कह कर। डेटामॉडेलिंग एक कला शायद ही कभी वेबसाइडर्स / -प्रोग्रामर्स के बीच पाई जाती है। कोई अपराध नहीं है, लेकिन यह समझाता है कि MyISAM का इतना उपयोग किया जा रहा है।


31

InnoDB प्रदान करता है:

ACID transactions
row-level locking
foreign key constraints
automatic crash recovery
table compression (read/write)
spatial data types (no spatial indexes)

InnoDB में TEXT और BLOB को छोड़कर एक पंक्ति में सभी डेटा 8,000 बाइट्स पर कब्जा कर सकते हैं। कोई पूर्ण पाठ अनुक्रमण InnoDB के लिए उपलब्ध नहीं है। InnoDB में COUNT (*) (जब, ग्रुप बाय या जोइन का उपयोग नहीं किया जाता है) MyISAM की तुलना में धीमी गति से निष्पादित होता है क्योंकि पंक्ति गणना आंतरिक रूप से संग्रहीत नहीं होती है। InnoDB एक फ़ाइल में डेटा और इंडेक्स दोनों को संग्रहीत करता है। InnoDB डेटा और इंडेक्स दोनों को कैश करने के लिए एक बफर पूल का उपयोग करता है।

MyISAM प्रदान करता है:

fast COUNT(*)s (when WHERE, GROUP BY, or JOIN is not used)
full text indexing
smaller disk footprint
very high table compression (read only)
spatial data types and indexes (R-tree)

MyISAM में टेबल-लेवल लॉकिंग है, लेकिन रो-लेवल लॉकिंग नहीं है। कोई लेन-देन नहीं। कोई स्वचालित क्रैश पुनर्प्राप्ति नहीं है, लेकिन यह मरम्मत तालिका की कार्यक्षमता प्रदान करता है। कोई विदेशी कुंजी बाधा नहीं। InnoDB तालिकाओं की तुलना में MyISAM टेबल आमतौर पर डिस्क पर आकार में अधिक कॉम्पैक्ट होती हैं। यदि आवश्यक हो तो Myisampack के साथ संपीड़ित करके MyISAM तालिकाओं को आकार में और अधिक कम किया जा सकता है, लेकिन केवल पढ़ने के लिए ही बनें। MyISAM एक फ़ाइल में अनुक्रमित करता है और दूसरे में डेटा। MyISAM, कैशिंग इंडेक्स के लिए कुंजी बफ़र्स का उपयोग करता है और ऑपरेटिंग सिस्टम के लिए डेटा कैशिंग प्रबंधन को छोड़ देता है।

कुल मिलाकर मैं सबसे अधिक प्रयोजनों के लिए InnoDB और केवल विशेष उपयोगों के लिए MyISAM की सिफारिश करूंगा। InnoDB अब नए MySQL संस्करणों में डिफ़ॉल्ट इंजन है।


2
fwiw, InnoDB में VARCHAR भी ओवरफ्लो पेजों पर जा सकते हैं, जैसे BLOB और TEXT करते हैं। इन सभी डेटा प्रकारों को आंतरिक रूप से समान रूप से संग्रहीत किया जाता है।
बिल कार्विन

जानकर अच्छा लगा, @BillKarwin! हम अपने ऐप में VARCHAR का भारी उपयोग करते हैं और VARCHAR का इस ~ 8kB की सीमा में योगदान होता है।
रिनोगो

अधिक जानकारी के लिए mysqlperformanceblog.com/2010/02/09/blob-storage-in-innodb देखें ।
बिल करविन

MySQL संस्करण 5.6+ में इनोडोड इंजन के रूप में उत्तर देने की तारीख तक का उत्तर नहीं है, आजकल पूर्ण पाठ अनुक्रमण का भी समर्थन करता है और साथ ही MySQL 5.5 + / 5.7 + स्थानिक डेटा प्रकार (5.5+) और स्थानिक अनुक्रमित (r-tee (5.7+) का समर्थन करता है .. सबसे अच्छे समर्थन के लिए आपको MySQL संस्करण 5.7+
रेमंड

25

यदि आप MyISAM का उपयोग करते हैं, तो आप प्रति घंटे कोई भी लेन-देन नहीं करेंगे , जब तक कि आप प्रत्येक DML कथन को लेनदेन नहीं मानते हैं (जो किसी भी स्थिति में, दुर्घटना की स्थिति में टिकाऊ या परमाणु नहीं होगा)।

इसलिए मुझे लगता है कि आपको InnoDB का उपयोग करना होगा।

300 लेनदेन प्रति सेकंड लगता है जैसे काफी। अगर आपको पूरी तरह से बिजली की विफलता के दौरान इन लेन-देन को टिकाऊ बनाने की आवश्यकता है, तो सुनिश्चित करें कि आपका I / O सबसिस्टम प्रति सेकंड कई लिखता है। आपको बैटरी समर्थित कैश के साथ कम से कम एक RAID नियंत्रक की आवश्यकता होगी।

यदि आप एक छोटा स्थायित्व हिट ले सकते हैं, तो आप InnoDB का उपयोग innodb_flush_log_at_trx_commit के साथ 0 या 2 पर सेट कर सकते हैं (विवरण के लिए डॉक्स देखें), आप प्रदर्शन में सुधार कर सकते हैं।

ऐसे कई पैच हैं जो Google और अन्य लोगों से संगति बढ़ा सकते हैं - ये आपकी रुचि के हो सकते हैं यदि आप अभी भी उनके बिना पर्याप्त प्रदर्शन प्राप्त नहीं कर सकते हैं।


24

प्रश्न और अधिकांश उत्तर पुराने हैं

हां, यह एक पुरानी पत्नियों की कहानी है कि MyISAM InnoDB से तेज है। प्रश्न की तारीख पर ध्यान दें: 2008; यह अब लगभग एक दशक बाद है। InnoDB ने तब से महत्वपूर्ण प्रदर्शन प्रगति की है।

नाटकीय ग्राफ एक मामले के लिए था जहां MyISAM जीतता है: एक खंड के COUNT(*) बिनाWHERE । लेकिन क्या यह सच है कि आप अपना समय क्या कर रहे हैं?

यदि आप समवर्ती परीक्षा चलाते हैं , तो InnoDB जीतने की संभावना है, यहां तक ​​कि खिलाफ भीMEMORY

यदि आप बेंचमार्किंग करते समय कोई भी लिखते हैं SELECTs, तो MyISAM और MEMORYटेबल-लेवल लॉकिंग के कारण खोने की संभावना है।

वास्तव में, Oracle इतना निश्चित है कि InnoDB बेहतर है कि उनके पास 8.0 से MyISAM को हटा दिया गया है।

प्रश्न जल्दी 5.1 के दिनों में लिखा गया था। तब से, इन प्रमुख संस्करणों को "सामान्य उपलब्धता" के रूप में चिह्नित किया गया था:

  • 2010: 5.5 (.8 दिसंबर में)
  • 2013: 5.6 (फ़रवरी में .10)
  • 2015: 5.7 (अक्टूबर में 9।)
  • 2018: 8.0 (अप्रैल में .11)

नीचे पंक्ति: MyISAM का उपयोग न करें


2
MySQL डेटाबेस प्रौद्योगिकी अग्रिम। और StackOverflow सवाल और जवाब अतीत में mired रहते हैं। मुख्य MyISAM और InnoDB के बीच मतभेद हैं कम के बारे में सर्वर पर "लोड", और अधिक के लिए समर्थन के बारे में रेफेरेंन्शिअल सत्यनिष्ठा और लेन-देन है, साथ ही संगामिति और वसूली (+10)
spencer7593

12

इसके अलावा MySQL के लिए कुछ ड्रॉप-इन प्रतिस्थापन की जाँच करें:

MariaDB

http://mariadb.org/

MariaDB एक डेटाबेस सर्वर है जो MySQL के लिए ड्रॉप-इन प्रतिस्थापन कार्यक्षमता प्रदान करता है। MariaDB, MySQL के कुछ मूल लेखकों द्वारा बनाया गया है, जिसमें फ्री और ओपन सोर्स सॉफ्टवेयर डेवलपर्स के व्यापक समुदाय की सहायता है। MySQL की मुख्य कार्यक्षमता के अलावा, MariaDB वैकल्पिक भंडारण इंजन, सर्वर अनुकूलन, और पैच सहित फीचर एन्हांसमेंट का एक समृद्ध सेट प्रदान करता है।

पर्कोना सर्वर

https://launchpad.net/percona-server

बेहतर प्रदर्शन, बेहतर डायग्नोस्टिक्स और अतिरिक्त सुविधाओं के साथ MySQL के लिए एक उन्नत ड्रॉप-इन प्रतिस्थापन।


1
मैं उन दोनों का उपयोग कर रहा हूं (उत्पादन में पेरकोना, विंडोज़-विकास पर मारिया)। वे तेजी से उठते हैं और पूरी तरह से काम करते हैं।
मोशे एल

4
इस सवाल का जवाब नहीं है। MariaDB और Percona MySQL के कांटे हैं, और InnoDB और MyISAM इंजन का भी उपयोग करते हैं।
15

12

कृपया ध्यान दें कि मेरी औपचारिक शिक्षा और अनुभव ओरेकल के साथ है, जबकि MySQL के साथ मेरा काम पूरी तरह से व्यक्तिगत और अपने समय पर किया गया है, इसलिए यदि मैं उन चीजों को कहता हूं जो ओरेकल के लिए सत्य हैं, लेकिन MySQL के लिए सही नहीं हैं, तो मैं माफी चाहता हूं। जबकि दो प्रणालियाँ बहुत कुछ साझा करती हैं, रिलेशनल सिद्धांत / बीजगणित समान है, और रिलेशनल डेटाबेस अभी भी रिलेशनल डेटाबेस हैं, फिर भी बहुत अंतर हैं !!

मैं विशेष रूप से (साथ ही पंक्ति-स्तरीय लॉकिंग) को पसंद करता हूं कि InnoDB लेनदेन-आधारित है, जिसका अर्थ है कि आप अपने वेब एप्लिकेशन के एक "ऑपरेशन" के लिए कई बार अपडेट / इंसर्टिंग / क्रिएट / चेंजिंग / ड्रॉपिंग / आदि कर सकते हैं। जो समस्या उत्पन्न होती है, वह यह है कि यदि उनमें से कुछ ही परिवर्तन / संचालन समाप्त हो रहे हैं, लेकिन अन्य नहीं करते हैं, तो आप ज्यादातर बार (डेटाबेस के विशिष्ट डिजाइन के आधार पर) एक डेटाबेस के साथ परस्पर विरोधी डेटा / संरचना के साथ समाप्त होते हैं।

नोट: ओरेकल के साथ, स्टेटमेंट्स को बदलने / बदलने / ड्रॉप करने को "डीडीएल" (डेटा डेफिनिशन) स्टेटमेंट कहा जाता है, और अंतर्निहित रूप से एक प्रतिबद्ध ट्रिगर होता है। "डीएमएल" (डेटा मैनिपुलेशन) नामक स्टेटमेंट डालें / अपडेट / डिलीट करें, नहीं हैं स्वचालित रूप से प्रतिबद्ध , लेकिन केवल तभी जब डीडीएल, कमिटमेंट, या एग्जिट / एक्ज़िट किया जाता है (या यदि आप अपना सत्र "ऑटो कमिट" सेट करते हैं, या यदि आपका क्लाइंट ऑटो-कमिट करता है)। ओरेकल के साथ काम करते समय इसके बारे में पता होना अनिवार्य है, लेकिन मुझे यकीन नहीं है कि MySQL दो प्रकार के बयानों को कैसे संभालता है। इस वजह से, मैं यह स्पष्ट करना चाहता हूं कि जब यह MySQL की बात आती है तो मुझे इस पर यकीन नहीं है; केवल ओरेकल के साथ।

लेन-देन आधारित इंजनों के बहिष्कार का एक उदाहरण:

मान लीजिए कि मैं या आप एक स्वतंत्र कार्यक्रम में भाग लेने के लिए साइन अप करने के लिए एक वेब-पेज पर हैं, और सिस्टम का एक मुख्य उद्देश्य केवल 100 लोगों को साइन अप करने की अनुमति देना है, क्योंकि यह बैठने की सीमा है घटना के लिए। एक बार 100 साइन-अप हो जाने के बाद, सिस्टम आगे के साइनअप को अक्षम कर देगा, कम से कम जब तक अन्य रद्द नहीं करेंगे।

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

अब हमारे पास अतिथि तालिका में एक अतिथि जोड़ा गया है, लेकिन उपलब्ध सीटों की संख्या अब गलत है (उदाहरण के लिए, मूल्य 85 है जब यह वास्तव में 84 है)।

बेशक , इसे संभालने के कई तरीके हैं, जैसे "मेहमानों की तालिका में 100 मिनट की पंक्तियों की संख्या के साथ उपलब्ध सीटों को ट्रैक करना," या कुछ कोड जो यह जांचते हैं कि जानकारी संगत है, आदि .... लेकिन लेनदेन-आधारित डेटाबेस के साथ। इंजन जैसे कि InnoDB, या तो सभी संचालन के लिए प्रतिबद्ध हैं, या कोई भी नहीं है उनमें से हैं। यह कई मामलों में मददगार हो सकता है, लेकिन जैसा मैंने कहा, यह सुरक्षित होने का एकमात्र तरीका नहीं है, नहीं (एक अच्छा तरीका है, हालांकि, डेटाबेस द्वारा नियंत्रित किया जाता है, प्रोग्रामर / स्क्रिप्ट-लेखक नहीं)।

यह सब "लेन-देन-आधारित" अनिवार्य रूप से इस संदर्भ में है, जब तक कि मैं कुछ याद नहीं कर रहा हूं - कि या तो पूरा लेनदेन सफल हो जाए जैसा कि होना चाहिए, या कुछ भी नहीं बदला है, क्योंकि केवल आंशिक परिवर्तन करने से मामूली गड़बड़ हो सकती है डेटाबेस, शायद यह भी भ्रष्ट ...

लेकिन मैं इसे एक बार और कहूंगा, यह केवल गड़बड़ करने से बचने का एकमात्र तरीका नहीं है। लेकिन यह उन तरीकों में से एक है जो इंजन खुद को संभालता है, आपको कोड / स्क्रिप्ट को छोड़कर केवल इस बारे में चिंता करने की ज़रूरत है कि "लेनदेन सफल था या नहीं, और मैं क्या करूँ (जैसे कि फिर से प्रयास करें)," बजाय मैन्युअल रूप से डेटाबेस के बाहर से इसे "मैन्युअल रूप से" जांचने के लिए कोड लिखना, और इस तरह के आयोजनों के लिए बहुत अधिक काम करना।

अंत में, टेबल-लॉकिंग बनाम पंक्ति-लॉकिंग के बारे में एक नोट:

अस्वीकरण: मैं MySQL के संबंध में निम्नलिखित सभी गलत हो सकता है, और काल्पनिक / उदाहरण स्थितियों में ध्यान देने योग्य बातें हैं, लेकिन मैं वास्तव में गलत हो सकता है में MySQL के साथ भ्रष्टाचार हो सकता है। सामान्य प्रोग्रामिंग में उदाहरण बहुत वास्तविक हैं, भले ही MySQL में ऐसी चीजों से बचने के लिए अधिक तंत्र हैं ...

वैसे भी, मैं उन लोगों के साथ सहमत होने में काफी आश्वस्त हूं जिन्होंने तर्क दिया है कि एक समय में कितने कनेक्शनों की अनुमति है एक बंद टेबल के आसपास काम नहीं करता है । वास्तव में, कई कनेक्शन एक टेबल को लॉक करने के पूरे बिंदु हैं !! ताकि अन्य प्रक्रियाएं / उपयोगकर्ता / एप्लिकेशन एक ही समय में परिवर्तन करके डेटाबेस को दूषित न कर सकें।

एक ही पंक्ति में काम करने वाले दो या दो से अधिक कनेक्शन आपके लिए वास्तव में कितना दिन बना सकते हैं ?? मान लें कि दोनों प्रक्रियाएँ एक ही पंक्ति में समान मूल्य को अपडेट करने की आवश्यकता / दोनों हैं, मान लीजिए कि पंक्ति बस टूर का रिकॉर्ड है, और दोनों प्रक्रियाएँ एक साथ "राइडर्स" या "उपलब्ध_सैट" को अपडेट करना चाहती हैं। फ़ील्ड को "वर्तमान मान प्लस 1" के रूप में

आइए इसे काल्पनिक रूप से करें, चरण दर चरण:

  1. प्रक्रिया एक वर्तमान मान को पढ़ती है, मान लें कि यह खाली है, इस प्रकार अब तक '0' है।
  2. प्रक्रिया दो वर्तमान मान को भी पढ़ती है, जो अभी भी 0 है।
  3. प्रक्रिया एक लिखते हैं (वर्तमान + 1) जो 1 है।
  4. प्रक्रिया दो को 2 लिखना चाहिए , लेकिन चूंकि यह नया मूल्य लिखने से पहले प्रक्रिया का वर्तमान मूल्य पढ़ता है , इसलिए यह तालिका में 1 भी लिखता है।

मुझे यकीन नहीं है कि दो कनेक्शन इस तरह से परस्पर जुड़ सकते हैं, दोनों पहले एक ही लिखते हैं ... लेकिन अगर नहीं, तो मैं अभी भी एक समस्या देखूंगा:

  1. प्रक्रिया एक वर्तमान मान पढ़ती है, जो 0 है।
  2. प्रक्रिया एक लिखते हैं (वर्तमान + 1), जो 1 है।
  3. प्रक्रिया दो वर्तमान मान को पढ़ती है। लेकिन जब एक डीआईडी ​​लिखने (अपडेट) की प्रक्रिया होती है, तो उसने डेटा को प्रतिबद्ध नहीं किया है, इस प्रकार केवल वही प्रक्रिया नए मूल्य को पढ़ सकती है जिसे उसने अपडेट किया है, जबकि अन्य सभी पुराने मूल्य को देखते हैं, जब तक कि कोई प्रतिबद्ध नहीं है।

इसके अलावा, कम से कम ओरेकल डेटाबेस के साथ, अलगाव स्तर हैं, जो मैं अपना समय बर्बाद करने की कोशिश नहीं करूंगा। यहाँ उस विषय पर एक अच्छा लेख है, और प्रत्येक अलगाव स्तर के पेशेवरों और विपक्ष हैं, जो एक डेटाबेस में महत्वपूर्ण लेनदेन आधारित इंजन के साथ कैसे जा सकते हैं ...

अंत में, विदेशी-कुंजियों और लेनदेन-आधारित बातचीत के बजाय, MyISAM के भीतर अलग-अलग सुरक्षा उपाय हो सकते हैं। खैर, एक के लिए, एक तथ्य यह है कि एक पूरी तालिका लॉक है, जिससे यह कम संभावना है कि लेनदेन / एफके की आवश्यकता है

और अफसोस, अगर आप इन समसामयिक मुद्दों के बारे में जानते हैं, तो हाँ आप इसे कम सुरक्षित खेल सकते हैं और बस अपने एप्लिकेशन लिख सकते हैं, अपने सिस्टम सेट कर सकते हैं ताकि इस तरह की त्रुटियां संभव न हों (डेटाबेस के बजाय आपका कोड ज़िम्मेदार है)। हालांकि, मेरी राय में, मैं कहूंगा कि रक्षात्मक रूप से प्रोग्रामिंग करना, हमेशा संभव के रूप में कई सुरक्षा उपायों का उपयोग करना सबसे अच्छा है, और हमेशा इस बात से अवगत रहें कि मानव त्रुटि पूरी तरह से बचना असंभव है। यह हर किसी के लिए होता है, और जो कोई भी कहता है कि वे इसके लिए प्रतिरक्षा हैं, झूठ बोलना चाहिए, या "हैलो वर्ल्ड" एप्लिकेशन / स्क्रिप्ट लिखने से अधिक नहीं किया है। ;-)

मुझे आशा है कि कुछ का कुछ एक के लिए उपयोगी है, और इससे भी अधिक-तो, मुझे आशा है कि मैं अभी मान्यताओं का दोषी नहीं रहा हूं और गलती से एक इंसान होने के नाते !! यदि ऐसा है तो मेरी क्षमायाचना, लेकिन उदाहरणों के बारे में सोचने के लिए अच्छा है, जोखिम के बारे में शोध करें, और इसी तरह, भले ही वे इस विशिष्ट संदर्भ में संभावित न हों।

मुझे ठीक करने के लिए स्वतंत्र महसूस करें, इस "उत्तर" को संपादित करें, यहां तक ​​कि इसे नीचे वोट करें। बस कृपया एक दूसरे के साथ मेरी बुरी धारणा को सुधारने के बजाय, सुधारने का प्रयास करें। ;-)

यह मेरी पहली प्रतिक्रिया है, इसलिए कृपया सभी अस्वीकरणों के कारण लंबाई को क्षमा करें, आदि ... मैं बिल्कुल अभिमानी नहीं करना चाहता जब मैं बिल्कुल निश्चित नहीं हूं!



5

मेरे अनुभव में, जब तक आप DELETEs, UPDATEs, एक बहुत सारे INSERT, लेनदेन और पूर्ण-पाठ अनुक्रमण नहीं करते, तब तक MyISAM एक बेहतर विकल्प था। BTW, चेक टेबल भयानक है। जैसा कि तालिका पंक्तियों की संख्या के संदर्भ में पुरानी हो जाती है, आपको नहीं पता कि यह कब समाप्त होगा।


2
पूर्ण-पाठ अनुक्रमण केवल MyISAM के साथ संभव है, InnoDB के साथ नहीं।
पिक्सेल हाथी

2
@PixelElephant, जो MySQL 5.6 में बदलना शुरू कर रहा है। InnoDB में फुलटेक्स्ट इंडेक्स टाइप है, लेकिन अभी तक यह IMHO प्रोडक्शन यूज़ के लिए तैयार नहीं है।
बिल कार्विन

1
"पूर्ण-पाठ अनुक्रमण केवल MyISAM के साथ संभव है, InnoDB के साथ नहीं": MySQL> = 5.6 के बाद से और अधिक सच नहीं है। Dev.mysql.com/doc/refman/5.6/en/fulltext-search.html देखें ।
हिबोउ57

5

मैंने यह पता लगा लिया है कि भले ही Myisam में लॉकिंग कंटेस्टेंट है, फिर भी यह ज्यादातर परिदृश्यों में InnoDb की तुलना में तेज़ है क्योंकि यह तेजी से लॉक अधिग्रहण योजना का उपयोग करता है। मैंने कई बार इनोडब की कोशिश की है और हमेशा एक कारण या दूसरे के लिए MyIsam में वापस आता हूं। इसके अलावा InnoDB विशाल लेखन भार में बहुत सीपीयू गहन हो सकता है।


4

डेटाबेस का उपयोग करने के लिए हर एप्लिकेशन का अपना प्रदर्शन प्रोफ़ाइल होता है, और संभावना है कि यह समय के साथ बदल जाएगा।

सबसे अच्छी बात यह है कि आप अपने विकल्पों का परीक्षण कर सकते हैं। MyISAM और InnoDB के बीच स्विचिंग तुच्छ है, इसलिए अपनी साइट के खिलाफ कुछ परीक्षण डेटा और फायर जिमर लोड करें और देखें कि क्या होता है।


4

मैंने MyISAM और InnoDB तालिकाओं में यादृच्छिक डेटा के सम्मिलन को चलाने की कोशिश की। परिणाम काफी चौंकाने वाला था। MyISAM को सिर्फ 10 हजार के लिए InnoDB की तुलना में 1 मिलियन पंक्तियाँ डालने के लिए कुछ सेकंड कम की आवश्यकता थी!


2
आप उसी प्रदर्शन को प्राप्त करेंगे, यदि आप लेनदेन का उपयोग करते हैं और InnoDB इंजन के लिए स्वतः पूर्णता बंद करते हैं।
stanleyxu2005

IDK अगर एक ही प्रदर्शन है, लेकिन यह है कि मैं और अधिक जटिल applicatinos में क्या करता हूं और यह इसे गति देता है।
user965748

1
आप अपने प्रयोग का सटीक विवरण प्रदान करने में विफल रहे - कौन सी कॉन्फ़िगरेशन सेटिंग्स? तालिका में पहले क्या था? किस तरह का डेटा? और शायद सबसे महत्वपूर्ण बात - क्या अनुक्रमिक आवेषण थे? समानांतर? उनकी टाइमिंग क्या थी? कितने CPU कोर? धागे? आदि
ईनपोकलम

3

myisam उस प्रकार के वर्कलोड के लिए एक NOGO है (उच्च संगामिति लिखता है), मेरे पास न तो इतना अनुभव है कि न इनडोडब (यह 3 बार परीक्षण किया गया है और प्रत्येक मामले में पाया गया कि प्रदर्शन चूसा है, लेकिन यह अंतिम परीक्षण के बाद से थोड़ी देर के लिए है यदि आप 'mysql' को चलाने के लिए मजबूर नहीं किया जाता है, एक कोशिश को स्वीकार करने पर विचार करें क्योंकि यह समवर्ती को बेहतर ढंग से लिखती है


3

संक्षेप में, यदि आप किसी ऐसी चीज़ पर काम कर रहे हैं, जो एक विश्वसनीय डेटाबेस की ज़रूरत है, तो इनोबीडी अच्छा है जो बहुत सारे INSERT और UPD निर्देशों को संभाल सकता है।

और, MyISAM अच्छा है यदि आपको एक डेटाबेस की आवश्यकता है जो कि टेबल-लॉक चीज़ पर इसकी कमियों पर विचार करते हुए, लिखने (INSERT और UPDATES) के बजाय अधिकतर पढ़ने (SELECT) निर्देशों को ले जाएगा।

आप जांच कर सकते हैं;
इनोबीडी के
पेशेवरों और विपक्ष पेशेवरों और MyISAM के विपक्ष


2

मुझे पता है कि यह लोकप्रिय नहीं होगा लेकिन यहाँ जाता है:

myISAM में लेन-देन और संदर्भात्मक अखंडता जैसे डेटाबेस अनिवार्य के लिए समर्थन का अभाव है जिसके परिणामस्वरूप अक्सर गड़बड़ / छोटी गाड़ी के आवेदन होते हैं। यदि वे आपके db इंजन द्वारा समर्थित नहीं हैं, तो आप उचित डेटाबेस डिज़ाइन के मूल सिद्धांतों को नहीं सीख सकते।

डेटाबेस की दुनिया में संदर्भात्मक अखंडता या लेनदेन का उपयोग नहीं करना सॉफ्टवेयर की दुनिया में ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग का उपयोग नहीं करने जैसा है।

InnoDB अब मौजूद है, इसके बजाय इसका उपयोग करें! यहां तक ​​कि MySQL डेवलपर्स ने अंततः इसे नए संस्करणों में डिफ़ॉल्ट इंजन में बदलने के लिए स्वीकार किया है, इसके बावजूद कि myISAM मूल इंजन था जो सभी विरासत प्रणालियों में डिफ़ॉल्ट था।

इससे कोई फर्क नहीं पड़ता कि आप पढ़ रहे हैं या लिख ​​रहे हैं या आपके पास क्या प्रदर्शन विचार हैं, myISAM का उपयोग करने से कई प्रकार की समस्याएं हो सकती हैं, जैसे कि यह एक मैं बस में भाग गया: मैं एक डेटाबेस सिंक कर रहा था और उसी समय कोई और एक एप्लिकेशन को एक्सेस किया जिसने myISAM के लिए एक टेबल सेट एक्सेस किया। लेनदेन समर्थन की कमी और इस इंजन की आम तौर पर खराब विश्वसनीयता के कारण, इसने पूरे डेटाबेस को क्रैश कर दिया और मुझे मैन्युअल रूप से mysql को फिर से शुरू करना पड़ा!

पिछले 15 वर्षों के विकास में मैंने कई डेटाबेस और इंजन का उपयोग किया है। इस अवधि के दौरान लगभग एक दर्जन बार myISAM मुझ पर दुर्घटनाग्रस्त हुआ, केवल एक बार! और यह एक Microsoft SQL डेटाबेस था जहां कुछ डेवलपर ने दोषपूर्ण CLR कोड (सामान्य भाषा रनटाइम - मूल रूप से C # कोड जो डेटाबेस के अंदर निष्पादित होता है) लिखा था, यह बिल्कुल डेटाबेस इंजन की गलती नहीं थी।

मैं यहां अन्य उत्तरों से सहमत हूं जो कहते हैं कि उच्च उपलब्धता, उच्च प्रदर्शन वाले अनुप्रयोगों को myISAM का उपयोग नहीं करना चाहिए क्योंकि यह काम नहीं करेगा, यह हताशा-रहित अनुभव के परिणामस्वरूप मजबूत या स्थिर नहीं है। अधिक जानकारी के लिए बिल करविन का उत्तर देखें।

पीएस गोट्टा तब पसंद करते हैं जब मायसम फैबॉयस डाउनवोट हो जाते हैं लेकिन आपको यह नहीं बता सकते कि इस उत्तर का कौन सा हिस्सा गलत है।


5
मैं नीचे नहीं था, लेकिन अगर मैं यह सलाह है कि कभी नहीं उपयोग करने के लिए किया जाएगा। शब्द को कभी भी एक डेवलपर की शब्दावली में नहीं मारा जाना चाहिए ... चेतावनी 'कभी नहीं कहेंगे'।
हबसन ब्रोपा

1

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


1

लगभग हर बार जब मैं कोई नया प्रोजेक्ट शुरू करता हूं तो मैं यही सवाल करता हूं कि क्या मैं किसी नए जवाब के साथ आता हूं।

यह अंततः उबलता है - मैं MySQL का नवीनतम संस्करण लेता हूं और परीक्षण चलाता हूं।

मेरे पास टेबल हैं जहां मैं कुंजी / मान लुकअप करना चाहता हूं ... और यह सब है। मुझे हैश कुंजी के लिए मान (0-512 बाइट्स) प्राप्त करने की आवश्यकता है। इस डीबी पर बहुत अधिक लेनदेन नहीं होता है। तालिका को कभी-कभार (इसमें संपूर्णता) अपडेट मिलता है, लेकिन 0 लेनदेन।

इसलिए हम यहां एक जटिल प्रणाली के बारे में बात नहीं कर रहे हैं, हम एक साधारण खोज के बारे में बात कर रहे हैं, .. और कैसे (टेबल रैम निवासी बनाने के अलावा) हम प्रदर्शन को अनुकूलित कर सकते हैं।

मैं अन्य डेटाबेस (यानी NoSQL) पर परीक्षण करने के लिए भी यह देखने के लिए कि क्या कहीं भी मुझे फायदा मिल सकता है। मुझे सबसे बड़ा फायदा कुंजी मैपिंग में मिला है, लेकिन जहां तक ​​लुकअप जाता है, MyISAM वर्तमान में उन सभी में शीर्ष पर है।

यद्यपि, मैं MyISAM तालिकाओं के साथ वित्तीय लेन-देन नहीं करूंगा, लेकिन सरल लुकअप के लिए, आपको इसका परीक्षण करना चाहिए .. आमतौर पर 2x से 5x तक प्रश्न / सेकंड।

इसका परीक्षण करें, मैं बहस का स्वागत करता हूं।


1

यदि यह 70% आवेषण है और 30% पढ़ता है तो यह InnoDB की तरफ अधिक पसंद है।


0

नीचे की ओर: यदि आप डेटा के बड़े हिस्से पर चयन के साथ ऑफ़लाइन काम कर रहे हैं, तो MyISAM आपको बेहतर (बहुत बेहतर) गति देगा।

जब MyISAM असीम रूप से अधिक कुशल होता है तो कुछ स्थितियाँ InnoDB की तुलना में होती हैं: जब बड़े डेटा में हेरफेर ऑफ़लाइन (टेबल लॉक के कारण) होता है।

उदाहरण: मैं NOAA से एक csv फ़ाइल (15M रिकॉर्ड) में परिवर्तित कर रहा था जो कि वर्चूर फ़ील्ड्स को कुंजियों के रूप में उपयोग करती है। InnoDB हमेशा के लिए ले रहा था, यहां तक ​​कि स्मृति के बड़े हिस्से भी उपलब्ध थे।

यह csv (पहले और तीसरे क्षेत्र कुंजी हैं) का एक उदाहरण है।

USC00178998,20130101,TMAX,-22,,,7,0700
USC00178998,20130101,TMIN,-117,,,7,0700
USC00178998,20130101,TOBS,-28,,,7,0700
USC00178998,20130101,PRCP,0,T,,7,0700
USC00178998,20130101,SNOW,0,T,,7,

चूँकि मुझे क्या करने की आवश्यकता है ताकि मौसम संबंधी घटनाओं का एक बैच ऑफ़लाइन अपडेट हो, मैं डेटा प्राप्त करने के लिए MyISAM तालिका का उपयोग करता हूं और कुंजियों पर JOINS चलाता हूं ताकि मैं आने वाली फ़ाइल को साफ़ कर सकूं और VARCHAR फ़ील्ड्स को INT कुंजियों (जो संबंधित हों) से बदल सकें बाहरी तालिकाएँ जहाँ मूल VARCHAR मान संग्रहीत हैं)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.