MySQL तालिका में varchar लंबाई का महत्व


112

मेरे पास एक MySQL टेबल है जहां पंक्तियों को गतिशील रूप से डाला जाता है। क्योंकि मैं स्ट्रिंग्स की लंबाई के बारे में निश्चित नहीं हो सकता हूं और न ही उन्हें काट देना चाहता हूं, इसलिए मैं उन्हें वेरचर (200) बनाता हूं जो आम तौर पर मेरी जरूरत से बहुत बड़ा है। क्या एक varchar क्षेत्र को आवश्यकता से अधिक लंबाई देने में एक बड़ा प्रदर्शन हिट है?


VARCHAR(255) utf8mb4~ 150k पंक्तियों के साथ एकल अनुक्रमित स्तंभ के साथ एक तालिका 11.5MB मापा जाता है। VARCHAR(48) utf8mb4समान डेटा (अधिकतम लंबाई 46 वर्ण) के साथ एक अनुक्रमित स्तंभ के साथ एक तालिका का उपयोग 4.5 एमबी। प्रश्नों में वास्तव में एक बड़ा अंतर नहीं है, यह अनुक्रमित है। लेकिन इसमें क्वेरी I / O और डेटाबेस बैकअप जैसी चीजें शामिल हैं।
कोड 4 आर 7

जवाबों:


59

नहीं, इस अर्थ में कि यदि आप उस कॉलम में स्टोर किए गए मान हमेशा (कहते हैं) 50 से कम अक्षर हैं, तो कॉलम को उसी के समान घोषित करना varchar(50)या varchar(200)उसका प्रदर्शन करना।


9
बिल्कुल सच नहीं है। बिल करविन
हज्जाद

5
मुझे लगता है कि डॉक्स, बेंचमार्क या कुछ इसी तरह के जवाब का समर्थन किया जाना चाहिए।
गोखान साड़ी

301

एक संभावित प्रदर्शन प्रभाव है: MySQL में, अस्थायी टेबल और MEMORYटेबल एक VARCHARकॉलम को एक निश्चित लंबाई के कॉलम के रूप में संग्रहीत करते हैं, जो इसकी अधिकतम लंबाई तक गद्देदार होता है। यदि आप VARCHARस्तंभों को आपके द्वारा आवश्यक सबसे बड़े आकार की तुलना में बड़ा डिज़ाइन करते हैं, तो आप अपनी तुलना में अधिक मेमोरी का उपभोग करेंगे। यह कैश दक्षता, छँटाई गति, आदि को प्रभावित करता है।


33
+1। मुझे कुछ JDBC ड्राइवर भी लगते हैं जो पंक्तियों को पुनः प्राप्त करने के लिए बफ़र सेट करते समय अधिकतम आकार के लिए पर्याप्त स्थान आवंटित करते हैं। कहने की जरूरत नहीं है, इससे दांतों में बहुत अधिक जलन होती है और जब दांतों में कुछ हो जाता है (50000) बस अगर किसी का वास्तव में बड़ा आखिरी नाम है :-)
paxdiablo

21
+1। यह एक महत्वपूर्ण प्रभाव है और मेरा मानना ​​है कि यह इस प्रश्न का वास्तविक उत्तर है।
एमरे यजीसी

6
यह उत्तर और स्वीकृत उत्तर दोनों ही ओपी के सही उत्तर को समझने के लिए आवश्यक हैं।
kd8azz

2
वास्तव में, जब ऐसी MEMORYतालिका को बहुत बड़ा माना जाता है, तो इसे डिस्क पर लिखा जाता है, जिससे महत्वपूर्ण प्रदर्शन में गिरावट होती है।
टिम्मो

1
यह उत्तर निर्दिष्ट कर सकता है कि यह कौन से स्टोरेज इंजन के बारे में सच है (मैं ध्यान देता हूं कि dev.mysql.com/doc/refman/8.0/en/… यह इंगित करता है कि अस्थायी तालिकाएँ हमेशा MySQL 8 के रूप में InnoDB होती हैं; क्या इससे कुछ भी बदलता है? , और डॉक्स के लिंक के साथ जो इसके दावों का समर्थन करता है। स्टैक एक्सचेंज पर मैंने आपके आउटपुट के बारे में क्या देखा है, मुझे विश्वास है कि जब आपने यह लिखा था, तो आप सही थे, लेकिन चीजें बदल गई होंगी, और लिंक दोनों दूसरों के लिए एक अच्छा उदाहरण निर्धारित करेंगे और बाकी के लोगों को खोजने में मदद करेंगे। खुद के लिए इस तरह की जानकारी।
मार्क एमी

14

VARCHAR आपके द्वारा वर्णित स्थिति के लिए आदर्श है, क्योंकि यह "चर चरित्र" के लिए खड़ा है - सीमा, आपके उदाहरण के आधार पर, 200 वर्ण होंगे लेकिन कुछ भी कम स्वीकार किए जाते हैं और कॉलम के आवंटित आकार को नहीं भरेंगे।

VARCHAR भी कम जगह लेती है - मानों को एक-बाइट या दो-बाइट लंबाई उपसर्ग प्लस डेटा के रूप में संग्रहीत किया जाता है। लंबाई उपसर्ग मूल्य में बाइट्स की संख्या को इंगित करता है। यदि मान 255 बाइट्स से अधिक की आवश्यकता हो सकती है, तो एक स्तंभ बाइट का उपयोग करता है, यदि मान 255 बाइट्स की आवश्यकता नहीं है, दो लंबाई बाइट्स।

MySQL CHAR की तुलना VARCHAR डेटाटाइप से अधिक जानकारी के लिए, इस लिंक को देखें ।


1
MySQL स्टोरेज (CHAR और VARCHAR के बारे में) में सभी को इस उत्तर में उल्लिखित लिंक को पढ़ना चाहिए। धन्यवाद!
पास्कल

14

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

आपके मामले में कई प्रदर्शन लीक हैं जिनमें आप भाग सकते हैं: बड़े जुड़ाव लंबे समय तक लगभग असंभव हैं varchar स्तंभों के हैं। उन स्तंभों पर अनुक्रमण एक वास्तविक हत्यारा है। आपकी डिस्क को डेटा स्टोर करना होगा। एक मेमोरी पेज कम पंक्तियों को पकड़ सकता है और टेबल स्कैन बहुत धीमा होगा। साथ ही क्वेरी कैश यहां आपकी मदद करने की संभावना नहीं होगी।

आपको खुद से पूछना होगा: प्रति वर्ष कितने आवेषण हो सकते हैं? औसत लंबाई क्या है? क्या मुझे वास्तव में 200 से अधिक वर्णों की आवश्यकता है या क्या मैं अपने एप्लिकेशन फ्रंट-एंड में पकड़ सकता हूं, यहां तक ​​कि उपयोगकर्ताओं को अधिकतम लंबाई के बारे में सूचित करके? क्या मैं तेजी से अनुक्रमण और स्कैनिंग के लिए एक संकीर्ण एक में टेबल को विभाजित कर सकता हूं और अतिरिक्त, कम आकार के विस्तार के लिए आवश्यक डेटा रखने के लिए एक और एक? क्या मैं संभव varchar डेटा को श्रेणियों में टाइप कर सकता हूं और इसलिए कुछ डेटा को कुछ छोटे, शायद int या bool-type कॉलमों में निकाल सकता हूं और varchar कॉलम को इस तरह से संकीर्ण कर सकता हूं?

आप यहां बहुत कुछ कर सकते हैं। वास्तविक जीवन के मापा प्रदर्शन डेटा का उपयोग करके कदम से कदम उठाना और फिर पहले डिजाइन के साथ जाना सबसे अच्छा हो सकता है। सौभाग्य।


डिजाइन विकल्पों को सूचीबद्ध करने और प्रभाव की खोज के लिए +1। मेरे प्रश्न के लिए भी बहुत उपयोगी है। stackoverflow.com/q/12083089/181638
असद अब्राहिम

5
क्या उच्च अधिकतम लंबाई निर्धारित करने से कोई वास्तविक प्रदर्शन प्रभाव पड़ता है, या प्रदर्शन केवल वास्तविक आकार द्वारा निर्धारित किया जाता है?
पूल

5

प्रदर्शन? नहीं, डिस्क भंडारण? हाँ, लेकिन यह सस्ता और भरपूर है। जब तक आपका डेटाबेस टेराबाइट पैमाने पर नहीं बढ़ेगा, तब तक आप शायद ठीक हैं।


अजीब है कि इस जवाब को पोस्ट किए जाने के छह साल बाद डाउनवोट किया गया था और अन्य कोई भी नहीं थे। दृढ़ और क्षुद्र लगता है। इस उत्तर के बारे में कुछ भी गलत नहीं है। मध्यस्थ?
डफिमो

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

5

आप में से कुछ सोच रहे हैं कि varchar(200)डिस्क की तुलना में डिस्क पर अधिक टेबल आकार लेता है varchar(20)। यह मामला नहीं है। केवल जब आप 255 चार्ट से परे जाते हैं तो mysql varcharफ़ील्ड डेटा की लंबाई निर्धारित करने के लिए एक अतिरिक्त बाइट का उपयोग करता है ।


9
अस्थायी तालिकाओं और MEMORYतालिकाओं के लिए ऐसा नहीं है ।
ऑर्बिट

4
जब भी आपकी चुनिंदा क्वेरी एक अस्थायी तालिका (संचालन और अन्य कामों के बीच आदेश) का उपयोग करती है, तो यह varchar (200) को चार (200) में बदल देगी और प्रदर्शन को नुकसान होगा।
जॅमी

1

प्रदर्शन हिट हो सकते हैं - लेकिन आमतौर पर ऐसे स्तर पर नहीं होते हैं जो अधिकांश उपयोगकर्ताओं को नोटिस करते हैं।

जब प्रत्येक फ़ील्ड का आकार पहले से ज्ञात होता है, तो MySQL जानता है कि प्रत्येक फ़ील्ड / पंक्ति के बीच कितने बाइट्स हैं और सभी डेटा को पढ़े बिना पृष्ठ को आगे बढ़ा सकते हैं। चर वर्णों का उपयोग अनुकूलन के लिए इस क्षमता को मंद करता है।

क्या डेटा विखंडन के कारण प्रदर्शन में varchar का परिणाम होता है?

इससे भी बेहतर, चर बनाम चरचर

सबसे उपयोगों के लिए, आप या तो साथ ठीक हो जाओगे - लेकिन वहाँ है एक अंतर है, और बड़े पैमाने पर डेटाबेस के लिए, वहाँ कारणों से आप एक या अन्य लेने चाहते हैं।


0

केवल चार के बजाय varchar होने के कारण, आकार अपनी वास्तविक लंबाई और स्ट्रिंग को इंगित करने के लिए आंतरिक क्षेत्र पर आधारित है। तो varchar (200) का उपयोग करना varchar (150) का उपयोग करने के लिए बहुत अलग नहीं है, सिवाय इसके कि आपके पास अधिक स्टोर करने की क्षमता है।

और आपको इस बात पर विचार करना चाहिए कि जब एक पंक्ति बढ़ती है, तो अपडेट पर क्या होता है। लेकिन अगर यह दुर्लभ है, तो आपको ठीक होना चाहिए।


0

डेटाटाइप नाम के अनुसार, यह VARCHAR यानी चर वर्ण डेटा संग्रहण है, mysql इंजन स्वयं को संग्रहीत डेटा के अनुसार उपयोग की जा रही मेमोरी आवंटित करता है, इसलिए मेरे ज्ञान के अनुसार कोई प्रदर्शन हिट नहीं है।


0

आपको अधिकांश स्थितियों में चार कॉलम के रूप में और उसी तरह से लंबाई निर्धारित करने की कोशिश करनी चाहिए, जिस तरह से आप एक वर्गाकार स्तंभ देख सकते हैं। आपको हमेशा var modifier के बारे में इतना नहीं सोचना चाहिए कि कुछ ऐसा हो जो आपके निर्णय लेने की अधिकतम लंबाई पर असर डालता हो। इसे वास्तव में एक प्रदर्शन संकेत के रूप में देखा जाना चाहिए बजाय इसके कि आपूर्ति किए गए तार अलग-अलग लंबाई के होंगे।

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

यदि आपके पास एक varchar (255) है, तो आपके पास कोई गारंटी नहीं है कि प्रदर्शन वार यह हमेशा किसी भी परिस्थिति में चार (255) के लिए किसी भी अलग तरह से व्यवहार करने वाला है।

भंडारण की आवश्यकताओं के बारे में मैनुअल में दी गई सलाह से इसे 255, 65535 आदि जैसे कुछ पर सेट करना आसान लग सकता है। इससे यह आभास होता है कि 0 (हाँ, यह एक बात है) और 255 के बीच के किसी भी मूल्य का समान प्रभाव होगा। हालांकि यह ऐसी चीज नहीं है जिसकी पूरी गारंटी हो।

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

यह कभी-कभी एक मुश्किल सवाल है, ठीक कितनी देर तक स्ट्रिंग का एक टुकड़ा होना चाहिए ताकि इसे उच्चतम सीमा तक स्थापित किया जा सके आपको पता है कि यह भीतर होना चाहिए लेकिन इसका कोई प्रभाव नहीं है। दुर्भाग्य से यह अक्सर उपयोगकर्ता को काम करने के लिए छोड़ दिया जाता है और यह वास्तव में कुछ हद तक मनमाना है। आप वास्तव में यह नहीं कह सकते कि कभी भी एक स्ट्रिंग की देखरेख न करें क्योंकि हो सकता है कि ऐसे मामले हों जहाँ आप बिल्कुल निश्चित नहीं हैं।

आपको यह सुनिश्चित करना चाहिए कि MySQL क्वेरीज एक एरर फेंकती है जब एक स्ट्रिंग ट्रंकट के बजाय बहुत लंबी होती है ताकि कम से कम आपको पता चले कि क्या यह एरर उत्सर्जन से बहुत कम हो सकता है। कॉलम को बड़ा या छोटा करने के लिए उनका आकार बदलना एक महंगा डीडीएल ऑपरेशन हो सकता है, इसे ध्यान में रखा जाना चाहिए।

चरित्र सेट पर भी विचार किया जाना चाहिए जहां लंबाई और प्रदर्शन खेलने में आता है। लंबाई बाइट्स के बजाय इसे संदर्भित करता है। यदि उदाहरण के लिए utf8 का उपयोग कर रहे हैं, (MB4 नहीं) तो varchar (255) वास्तव में varbinary (3 * 255) है। यह जानना मुश्किल है कि परीक्षण चलाने और स्रोत कोड / दस्तावेज को गहराई से देखे बिना इस तरह की चीजें वास्तव में कैसे खेलेंगी। इस वजह से अत्यधिक लंबाई के लिए अप्रत्याशित रूप से फुलाया प्रभाव पड़ने की गुंजाइश है। यह केवल प्रदर्शन पर लागू नहीं होता है। यदि आपको एक दिन एक वैरिकाज़ कॉलम के वर्ण सेट को एक बड़े से बदलने की आवश्यकता है, तो हो सकता है कि अगर आप कृतज्ञतापूर्वक लंबे तार मौजूद होने से बचा सकते हैं, तो आप बिना किसी संभोग के कुछ सीमा तक रोक सकते हैं। यह आम तौर पर एक काफी आला समस्या है, लेकिन यह सामने आता है,

यदि यह पता चला कि MAX (LENGTH (स्तंभ)) हमेशा <64 है (जैसे कि अगर यह निर्णय लिया गया था कि इनपुट पर एक सीमा होगी जो स्तंभ परिभाषा से मेल नहीं खाती थी) लेकिन आपके पास varchar (255) है तो एक है अच्छा मौका है कि आप कुछ परिदृश्यों में आवश्यकता से चार गुना अधिक स्थान का उपयोग करेंगे।

इसमें शामिल हो सकते हैं:

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

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

जब आप ऐसा नहीं कर सकते हैं, यदि आप संदेह के समय मामलों के लिए कुछ ऐसा करते हैं जैसे कि varchar (255) तो मैं विज्ञान करने की सलाह देता हूं। इसमें तालिका को डुप्लिकेट करना शामिल हो सकता है, var char कॉलम के आकार को कम करना और फिर उसमें डेटा को मूल से कॉपी करना और अनुक्रमणिका / पंक्ति डेटा के आकार को देखना (स्तंभ को भी अनुक्रमणित करना), इसे भी एक प्राथमिक कुंजी के रूप में आज़माएं पंक्तियों को प्राथमिक कुंजी द्वारा आदेशित किए जाने के कारण इनोबीडी में अलग तरह से व्यवहार किया जा सकता है)। बहुत कम से कम इस तरह से आपको पता चल जाएगा कि क्या आपके पास आईओ पर प्रभाव पड़ता है जो सबसे संवेदनशील बाधाओं में से एक है। मेमोरी के उपयोग के लिए परीक्षण करना अधिक कठिन है, यह कठिन रूप से परीक्षण करना मुश्किल है। मैं संभावित सबसे खराब मामलों की जांच करने की सलाह दूंगा (स्मृति परिणामों में बहुत सारे मध्यवर्ती के साथ प्रश्न, बड़े अस्थायी तालिकाओं के लिए व्याख्या के साथ जांच, आदि)।

यदि आप जानते हैं कि तालिका में बहुत सी पंक्तियाँ नहीं हैं, तो आप जॉइन, इंडेक्स (विशेष रूप से कंपोज़िट, यूनिक) आदि के लिए कॉलम का उपयोग नहीं करने जा रहे हैं, तो आपको सबसे अधिक समस्या नहीं होगी।

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