MySQL VARCHAR आकार के प्रदर्शन निहितार्थ


45

क्या varchar size के बीच MySQL में प्रदर्शन अंतर है? उदाहरण के लिए, varchar(25)और varchar(64000)। यदि नहीं, तो क्या यह सुनिश्चित करने का एक कारण है कि सभी वर्चरों को अधिकतम आकार के साथ घोषित नहीं किया जाए ताकि आप कमरे से बाहर न भाग सकें?


3
+1 यह प्रश्न सभी DBMS के समान है। मेरे अवलोकन से कई प्रकार के आकार विकसित होते हैं।
bernd_k

5
MySQL नहीं, लेकिन Depesz की यह ब्लॉग पोस्ट PostgreSQL के लिए आपके प्रश्न का उत्तर दे सकती है ।
xenoterracide

जवाबों:


29

आपको CHAR बनाम VARCHAR का उपयोग करने के tradeoffs का एहसास होना चाहिए

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

VARCHAR क्षेत्रों के साथ, आपको एक पूरी तरह से अलग कहानी मिलती है। उदाहरण के लिए VARCHAR (15) वास्तव में गतिशील रूप से 16 बाइट्स तक आवंटित करता है, डेटा के लिए 15 तक और, कम से कम, 1 अतिरिक्त बाइट डेटा की लंबाई को संग्रहीत करने के लिए। यदि आपके पास स्टोर करने के लिए स्ट्रिंग 'हैलो' है जो 6 बाइट्स लेगा, तो 5. स्ट्रिंग हेरफेर को हमेशा सभी मामलों में लंबाई की जाँच के कुछ प्रकार का प्रदर्शन करना होगा।

जब आप दो काम करते हैं तो ट्रेडऑफ अधिक स्पष्ट होता है:
1. लाखों या अरबों पंक्तियों का संग्रह करना
2. उन स्तंभों को अनुक्रमणित करना जो या तो CHAR या VARCHAR हैं

TRADEOFF # 1

जाहिर है, VARCHAR लाभ उठाता है क्योंकि चर-लंबाई डेटा छोटी पंक्तियों का उत्पादन करेगा और इस प्रकार, छोटी भौतिक फाइलें।

TRADEOFF # 2

चूंकि CHAR फ़ील्ड्स को निश्चित फ़ील्ड चौड़ाई के कारण कम स्ट्रिंग हेरफेर की आवश्यकता होती है, CHAR फ़ील्ड के विरुद्ध अनुक्रमणिका लुकअप औसत रूप से VARCHAR फ़ील्ड्स की तुलना में 20% अधिक तेज़ी से होता है। यह मेरी ओर से कोई अनुमान नहीं है। MySQL डेटाबेस डिजाइन और ट्यूनिंग पुस्तक ने इसे साबित करने के लिए एक MyISAM टेबल पर कुछ अद्भुत प्रदर्शन किया। पुस्तक में उदाहरण कुछ इस तरह था:

ALTER TABLE tblname ROW_FORMAT=FIXED;

यह निर्देश बल वाराह के रूप में व्यवहार करने के लिए हैं। मैंने 2007 में अपनी पिछली नौकरी में ऐसा किया था और बिना किसी और बदलाव के 300GB टेबल ले लिया और 20% तक इंडेक्स लुकअप किया। यह प्रकाशित के रूप में काम किया। हालाँकि, इसने लगभग एक टेबल का आकार लगभग दोगुना कर दिया, लेकिन यह केवल # 1 ट्रेडऑफ़ पर वापस जाता है।

आप यह देखने के लिए संग्रहीत डेटा का विश्लेषण कर सकते हैं कि MySQL कॉलम परिभाषा के लिए क्या सिफारिश करता है। बस किसी भी तालिका के खिलाफ निम्नलिखित चलाएँ:

SELECT * FROM tblname PROCEDURE ANALYSE();

यह संपूर्ण तालिका को आगे बढ़ाएगा और इसमें मौजूद डेटा, न्यूनतम फ़ील्ड मान, अधिकतम फ़ील्ड मान और इसके आगे के आधार पर प्रत्येक स्तंभ के लिए स्तंभ परिभाषाएँ सुझाएगा। कभी-कभी, आपको CHAR बनाम VARCHAR की योजना बनाने के साथ सामान्य ज्ञान का उपयोग करना होगा। यहाँ एक अच्छा उदाहरण है:

यदि आप IP पते स्टोर कर रहे हैं, तो ऐसे कॉलम के लिए मास्क अधिकतम 15 वर्णों (xxx.xxx.xxx.xxx) पर है। मैं दिल की धड़कन में CHAR (15) पर सही तरीके से कूदूंगा क्योंकि आईपी पते की लंबाई एक अतिरिक्त बाइट द्वारा नियंत्रित स्ट्रिंग हेरफेर की सभी और बहुत कुछ और अलग जटिलता नहीं होगी। आप इस तरह के कॉलम के खिलाफ अभी भी एक प्रक्रिया विश्लेषण () कर सकते हैं। यह VARCHAR की सिफारिश भी कर सकता है। मेरा पैसा अभी भी इस उदाहरण में VARCHAR पर CHAR पर होगा।

CHAR बनाम VARCHAR मुद्दों को उचित योजना के माध्यम से ही हल किया जा सकता है। बड़ी ताकत के साथ बड़ी जिम्मेदारी आती है (क्लिच लेकिन सच)


4
यदि आप IP पते संग्रहीत कर रहे हैं, तो मुझे उन्हें इंट के अलावा किसी अन्य चीज़ के रूप में संग्रहीत करने का कोई कारण नहीं दिखता है। यह सब एक आईपी पता है। कई भाषाओं में कुछ प्रकार के ip2int फ़ंक्शन हैं। यदि आप एक कमांड लाइन कॉल की अभिलाषा चाहते हैं, तो ABCD में परिवर्तित होने के लिए एक संग्रहीत कार्यविधि बनाना कठिन नहीं है: A pow (256,3) + b pow (256,2) + c * 256 + d
atxdba

1
इस बिंदु पर अधिक इर मुझे लगता है कि mysql का अपना ip2int फ़ंक्शन है: INET_ATON
atxdba

3
@atxdba: मेरे उत्तर की बात सिर्फ CHAR बनाम VARCHAR का उपयोग कर रही है। मैं सिर्फ एक उदाहरण के रूप में आईपी का उपयोग करता हूं क्योंकि इसका स्ट्रिंग चरित्र आकार 15. के करीब है। इस प्रकार, VARCHAR के पक्ष में एक स्थिर CHAR आकार को गोल करना केवल प्रश्न के लिए एक उदाहरण है। आईपी ​​पतों का प्रतिनिधित्व करने के बेहतर तरीकों के बारे में आपकी टिप्पणी काफी मान्य है और सबसे अधिक समझ में आता है।
रोलैंडमाइसीडीडीबीए

CHAR (15) 15 अक्षर आवंटित करता है , बाइट्स नहीं । Utf8 के लिए, वह 45 बाइट्स है
रिक जेम्स

2
जबकि यह CHAR / VARCHAR तुलना के बारे में एक अच्छा उत्तर है, प्रश्न विभिन्न VARCHAR आकारों के बारे में था।
कलेक्टर

13

इसका उत्तर वास्तव में जटिल है। संक्षिप्त संस्करण: एक अंतर है

  1. परिणामों (जैसे GROUP BYकथन) को फ़िल्टर करने के लिए अस्थायी टेबल बनाते समय , पूरी लंबाई आवंटित की जाएगी।

  2. वायर प्रोटोकॉल (क्लाइंट को पंक्तियाँ भेजना) संभवतः बड़ी लंबाई आवंटित करेगा।

  3. भंडारण इंजन एक उचित varchar लागू नहीं कर सकता / सकती है।

(2) मैं मानता हूं कि वायर प्रोटोकॉल कुछ ऐसा नहीं है जिससे मैं पूरी तरह परिचित हूं, लेकिन यहां सामान्य सलाह है कि लंबाई का अनुमान लगाने के लिए कम से कम कुछ न्यूनतम प्रयास लागू करें।


इशारा करते हुए कहा। MySQL 5.7 मान बफर (चर लंबाई) में पैक कर सकता है। यहाँ और अधिक विस्तार से बताया गया है: mysqlserverteam.com/…
मॉर्गन Tocker

9

इस सूत्र में अधिकांश उत्तर 5 साल पुराने हैं, जो पहले InnoDB और utf8 में लिखे गए थे, चूक थे। तो, मुझे शुरू करने दो ...

जब किसी क्वेरी को आंतरिक अस्थायी तालिका की आवश्यकता होती है तो वह तालिका का उपयोग करने की कोशिश करती है MEMORY। लेकिन MEMORY का उपयोग नहीं किया जा सकता है

  • TEXT/ BLOBकॉलम को लाया जा रहा है, नहीं भी TINYTEXT
  • VARCHAR कुछ राशि से बड़ा, वर्तमान संस्करण में शायद 512 है।

इसके अलावा, ध्यान दें कि VARCHARsबदल गए हैं CHARs। तो, स्तंभ में जो भी है, 765 बाइट्स के विस्तार के VARCHAR(255)साथ CHARACTER SET utf8। फिर, यह ट्रिगर किया जा सकता है:

  • यदि MEMORYतालिका max_heap_table_size या तो बड़ी हो जाती है याtmp_table_size , इसे MyISAM में बदल दिया जाएगा और डिस्क पर संभावित फैल जाएगा।

तो, रहने VARCHAR(25)की अधिक संभावना है MEMORY, इसलिए तेज हो। (255)उतना अच्छा नहीं है, और (64000)बुरा है।

(भविष्य में, अस्थायी सारणी शायद होंगी InnoDB, और इस उत्तर के हिस्से को संशोधित करने की आवश्यकता होगी।)


6

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


यह एक बहुत ही ताजा परिप्रेक्ष्य है। यदि यह वह पुस्तक है जिसका आप उल्लेख कर रहे हैं ( amazon.com/MySQL-High-Avucation-Building-Centers/dp/… ), तो कृपया अपने उत्तर में पुस्तक का पृष्ठ संख्या डालें, क्योंकि मैं इसे पढ़ना चाहूंगा। +1 !!!
रोलैंडमाइसीडीडीबीए

मूर्खतापूर्ण मुझे ... उच्च निष्पादन उपलब्ध नहीं है: amazon.com/High-Performance-MySQL-Optimization-Replication/dp/… ... पृष्ठ संख्या 236/237 है यह बताता है कि कैसे एक varchar स्तंभ को परिभाषित करने में उदारता नासमझ हो सकती है। हालांकि ध्यान रखें कि यह किताब वापस लिखी गई थी जब 5.1 बस बाहर थी। एक तीसरा संस्करण 5.5 में सभी बड़े बदलावों को शामिल करने के लिए अगले साल आ रहा है, इसलिए शायद यह बदल जाएगा :)
TechieGurl

पृष्ठ 236 में विशेष रूप से चार सेटों से संबंधित टकराव का उल्लेख है। VARCHAR के लिए यह बहुत बुरा होगा। पृष्ठ 237 पर, पृष्ठ 238 पर चित्र 5-5 के साथ क्लाइंट / सर्वर संचार के लिए सेटिंग्स एक और कारण दिखाते हैं। चरित्र के अनुवाद की प्रक्रिया आगे-पीछे होती है। फिर, VARCHAR के लिए एक और बुरा साहसिक।
रोलैंडमाइसीडीडीबीए

स्पष्ट करने के लिए, भले ही यह खंड स्पष्ट रूप से यह नहीं कहता है कि MySQL आकार बनाने के लिए जाएगा, हम जानते हैं कि जब एक ऑपरेशन को एक अस्थायी तालिका की आवश्यकता होती है तो वह तालिका MEMORY इंजन में होती है और THAT हमेशा स्ट्रिंग प्रकारों को फिक्स चंक्स में संग्रहीत करता है ताकि उदार कैसे बने रैम में रहने के विपरीत डिस्क पर जाने के लिए आवश्यक मेमोरी
टेम्‍परेरी

@ रोलैंडमाइसीडीडीबीए। हां ... वह भी ... टकराव भी यहां एक कारक बन जाता है (अगर आप UTF-8 का उपयोग करते हैं और गैर लैटिन वर्ण हैं) और यह सब बस तब मारता है जब एक मेमोरी इंजन टेबल के साथ काम करता है और डिस्क के लिए एक
तेज़

5

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


3

सुनिश्चित करें कि आप कमरे से बाहर नहीं चलते हैं

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

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

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