MySQL - varchar लंबाई और प्रदर्शन


19

क्या घोषित VARCHARआकार प्रदर्शन के लिए महत्वपूर्ण है? क्या (गति में) कोई अंतर है VARCHAR(50)और VARCHAR(255)? या लंबाई को परिभाषित करना तर्क / डिजाइन की बाधा है?


जवाबों:


31

यह एक बहुत ही सामान्य "परीक्षा / साक्षात्कार प्रश्न" है। मैं उतना ही अच्छा जवाब दूंगा जितना मैं कर सकता हूं:

InnoDB और MyISAM (डायनामिक / कॉम्पैक्ट) के लिए मानक पंक्ति स्वरूपों में ए VARCHAR(50)और VARCHAR(255)उसी तरह से स्ट्रिंग टेक्स्ट को स्टोर करेगा- लंबाई के लिए 1 बाइट और प्रति कैरेक्टर के आधार पर 1 और 4 बाइट्स के बीच वास्तविक स्ट्रिंग (एन्कोडिंग के आधार पर) वास्तविक चरित्र संग्रहीत)।

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

यह सच नहीं है VARCHAR(256), क्योंकि तब लंबाई के लिए 2 बाइट्स (कम से कम) हमेशा आवश्यक होते हैं।

तो, इसका मतलब है कि हमें हमेशा करना VARCHAR(255)चाहिए, क्या हमें नहीं करना चाहिए? नहीं, कई कारण हैं।

जबकि InnoDB एक डायनेमिक तरीके से varchar स्टोर कर सकता है, जो अन्य इंजनों के लिए सही नहीं है। MyISAM में एक निश्चित पंक्ति आकार प्रारूप है, और MEMORY तालिकाओं का आकार हमेशा तय होता है। क्या हमें उन अन्य इंजनों की परवाह करनी चाहिए? हां, हमें चाहिए, क्योंकि भले ही हम उन्हें सीधे उपयोग न करें, इंटरमीडिएट परिणाम (मेमोरी पर अस्थायी टेबल) के लिए मेमरी टेबल का उपयोग आमतौर पर किया जाता है , और जैसा कि परिणाम पहले से ज्ञात नहीं है, तालिका को अधिकतम आकार के साथ बनाना होगा संभव - VARCHAR(255)अगर वह हमारा प्रकार है। यदि आप बर्बाद हुए स्थान के बारे में सोच सकते हैं, यदि हम MySQL के एन्कोडिंग का उपयोग कर रहे हैं , तो 'utf8' charsetMEMORY लंबाई के लिए 2 बाइट आरक्षित करेगा + 3 * 255 बाइट्स प्रति पंक्ति(मानों के लिए जो केवल कुछ बाइट्स इनोबीडी पर ले सकते हैं)। यानी VARCHAR के लिए 1 मिलियन टेबल पर लगभग 1GB है। इतना ही नहीं अनावश्यक स्मृति तनाव का कारण बनता है, यह डिस्क पर किए जाने वाले कार्यों को उत्तेजित कर सकता है, संभवतः इसे हजारों बार धीमा कर सकता है। यह सब उसके परिभाषित डेटा प्रकार (सामग्री के स्वतंत्र रूप से) के खराब चयन के कारण है।

यह InnoDB के लिए कुछ परिणाम भी है। सूचकांक का आकार 3072 बाइट और एकल स्तंभ अनुक्रमणिका, 767 बाइट * तक सीमित है। तो, यह बहुत संभावना है कि आप पूरी तरह से एकVARCHAR(255) फ़ील्ड को इंडेक्स करने में सक्षम नहीं होंगे (यह मानकर कि आप utf8 या किसी अन्य चर लंबाई-एन्कोडिंग का उपयोग करते हैं)।

इसके अतिरिक्त, InnoDB के लिए अधिकतम इनलाइन पंक्ति का आकार आधा पृष्ठ (लगभग 8000 बाइट्स) है, और BLOB या varchar जैसे चर-लेन्थ फ़ील्ड्स को आधे पृष्ठ पर फिट नहीं होने पर ऑफ-पेज संग्रहीत किया जा सकता है । प्रदर्शन में कुछ परिणाम होते हैं (कभी-कभी अच्छे, कभी-कभी बुरे, उपयोग के आधार पर) जिन्हें अनदेखा नहीं किया जा सकता है। यह COMPACT और डायनामिक प्रारूपों के बीच कुछ विचित्रता का कारण बना। उदाहरण के लिए, देखें: त्रुटि 1118: पंक्ति का आकार बहुत बड़ा है। utf8 मासूम

पिछले नहीं बल्कि कम से कम, जैसा कि @ypercube ने मुझे याद दिलाया है, लंबाई के लिए 1 बाइट से अधिक की आवश्यकता हो सकती है भले ही आप उपयोग कर रहे हों VARCHAR(255), क्योंकि परिभाषा वर्णों में है, जबकि लंबाई बाइट्स को संग्रहीत करती है। उदाहरण के लिए REPEAT('ñ', 255)utf8 में 2 ^ 255 से अधिक बाइट्स हैं, इसलिए इसकी लंबाई को संग्रहीत करने के लिए 1 बाइट से अधिक की आवश्यकता होगी:

mysql> SELECT LENGTH(REPEAT('ñ', 255));
+---------------------------+
| LENGTH(REPEAT('ñ', 255))  |
+---------------------------+
|                       510 |
+---------------------------+
1 row in set (0.02 sec)

mysql> SELECT CHAR_LENGTH(REPEAT('ñ', 255));
+--------------------------------+
| CHAR_LENGTH(REPEAT('ñ', 255))  |
+--------------------------------+
|                            255 |
+--------------------------------+
1 row in set (0.00 sec)

तो सलाह का सामान्य टुकड़ा संभव है कि सबसे छोटे प्रकार का उपयोग करें , क्योंकि यह संभावित रूप से प्रदर्शन या प्रबंधन की समस्याएं पैदा कर सकता है। ए इससे VARCHAR(100)बेहतर है VARCHAR(255)(हालांकि VARCHAR(20)बेहतर होगा), भले ही आपको सटीक लंबाई पता न हो। रूढ़िवादी होने की कोशिश करें क्योंकि, जब तक कि तालिका बहुत बड़ी न हो, आप हमेशा बाद में परिभाषा बदल सकते हैं।

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

(*) दूसरा अपडेट : big_prefix_index अब नवीनतम MySQL संस्करणों (8.0) पर डिफ़ॉल्ट रूप से सक्षम है, लेकिन यह पुराने संस्करणों के लिए अभी भी सही है या यदि आप लैगसी इनोडब फाइल / पंक्ति प्रारूपों (गतिशील या संकुचित के अलावा) का उपयोग कर रहे हैं, लेकिन अब डिफ़ॉल्ट रूप से, एकल कॉलम इंडेक्स उन 3072 बाइट्स तक हो सकते हैं।


छोटा अद्यतन: MySQL-8.0.13 + अस्थायी तालिकाओं के लिए डिफ़ॉल्ट रूप से TempTable का उपयोग करता है जिसमें varchars के लिए कुशल भंडारण है।
डैनब्लैक

0

1- बनाम 2-बाइट उपसर्ग के बारे में भूल जाओ VARCHARs

  • यह ऋणात्मक राशि द्वारा प्रदर्शन को प्रभावित करता है।
  • स्पष्ट नियम के अनुसार यह "2" अधिक बार होता है।

255 के बारे में सवाल पूछा गया है और कई बार जवाब दिया गया है।

  • बहुत लंबे समय तक की VARCHARsविफलता हो सकती है CREATE TABLE
  • टेम्‍प टेबलों को MEMORYटेबलों VARCHARsमें बदल दिया जा सकता है VARCHAR। इसका मतलब है, उदाहरण के लिए, VARCHAR(255) CHARACTER SET utf8mb41020 बाइट्स की निश्चित लंबाई चाहिए। (यह विफल हो जाएगा, और यह MyISAM का उपयोग करने के लिए पतित होगा।)

नीचे पंक्ति: नेत्रहीन रूप से 255 (या 256) का उपयोग न करें; स्कीमा के लिए क्या मतलब है।

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