बीच utf8_general_ci
और utf8_unicode_ci
, वहाँ प्रदर्शन के मामले में कोई अंतर है?
utf8[mb4]_unicode_ci
, तो आप और भी अधिक पसंद कर सकते हैं utf8[mb4]_unicode_520_ci
।
utf8mb4_0900_ai_ci
।
बीच utf8_general_ci
और utf8_unicode_ci
, वहाँ प्रदर्शन के मामले में कोई अंतर है?
utf8[mb4]_unicode_ci
, तो आप और भी अधिक पसंद कर सकते हैं utf8[mb4]_unicode_520_ci
।
utf8mb4_0900_ai_ci
।
जवाबों:
ये दोनों टकराव UTF-8 वर्ण एन्कोडिंग के लिए दोनों हैं। अंतर यह है कि पाठ को कैसे क्रमबद्ध और तुलना किया जाता है।
नोट: MySQL में आपको इसके utf8mb4
बजाय उपयोग करना होगा utf8
। भ्रामक रूप से, utf8
प्रारंभिक MySQL संस्करणों से एक त्रुटिपूर्ण UTF-8 कार्यान्वयन है जो केवल पिछड़े संगतता के लिए बना हुआ है। निश्चित संस्करण को नाम दिया गया था utf8mb4
।
नोट: MySQL के नए संस्करणों ने यूनिकोड सॉर्टिंग नियमों को अपडेट किया है, utf8mb4_0900_ai_ci
जो यूनिकोड 9.0 के आधार पर समकक्ष नियमों के लिए उपलब्ध हैं - और इसके समकक्ष _general
संस्करण नहीं हैं। अब यह पढ़ लोग शायद बजाय या तो की इन नए collations में से एक का उपयोग करना चाहिए _unicode
या _general
। नीचे जो लिखा गया है, उसमें से कोई भी बहुत अधिक रुचि वाला नहीं है यदि आप इसके बजाय नए कॉलेक्शन में से एक का उपयोग कर सकते हैं।
मुख्य अंतर
utf8mb4_unicode_ci
सार्वभौमिक छँटाई और तुलना के लिए आधिकारिक यूनिकोड नियमों पर आधारित है, जो भाषाओं की एक विस्तृत श्रृंखला में सटीक रूप से सॉर्ट करता है।
utf8mb4_general_ci
सॉर्टिंग नियमों का एक सरलीकृत सेट है, जिसका उद्देश्य गति में सुधार के लिए डिज़ाइन किए गए कई शॉर्ट-कट लेते समय और साथ ही साथ करना है। यह यूनिकोड नियमों का पालन नहीं करता है और कुछ स्थितियों में अवांछनीय छँटाई या तुलना करेगा, जैसे कि विशेष भाषाओं या वर्णों का उपयोग करते समय।
आधुनिक सर्वरों पर, यह प्रदर्शन बूस्ट सभी लेकिन नगण्य होगा। यह ऐसे समय में तैयार किया गया था जब सर्वर में आज के कंप्यूटर के सीपीयू प्रदर्शन का एक छोटा सा अंश था।
के लाभ utf8mb4_unicode_ci
से अधिकutf8mb4_general_ci
utf8mb4_unicode_ci
, जो छँटाई और तुलना के लिए यूनिकोड नियमों का उपयोग करता है, भाषाओं की एक विस्तृत श्रृंखला में सही छँटाई के लिए और विशेष वर्णों की एक विस्तृत श्रृंखला का उपयोग करते समय एक काफी जटिल एल्गोरिथ्म को नियुक्त करता है। इन नियमों को भाषा-विशिष्ट सम्मेलनों को ध्यान में रखना चाहिए; हर कोई अपने पात्रों को उस तरह से नहीं लिखता, जिसे हम 'वर्णमाला क्रम' कहते हैं।
जहाँ तक लैटिन (यानी "यूरोपीय") भाषाओं में जाना है, यूनिकोड छँटाई और utf8mb4_general_ci
MySQL में सरलीकृत छँटाई के बीच बहुत अंतर नहीं है , लेकिन अभी भी कुछ अंतर हैं:
उदाहरण के लिए, यूनिकोड समतलीकरण "" "को" ss "की तरह, और" like "को" OE "की तरह उपयोग करता है, जैसा कि उन वर्णों का उपयोग करने वाले लोग सामान्य रूप से चाहते हैं, जबकि utf8mb4_general_ci
उन्हें एकल वर्ण (संभवतः" s "और" e "क्रमशः) ।
कुछ यूनिकोड वर्णों को आग्नेय के रूप में परिभाषित किया गया है, जिसका अर्थ है कि उन्हें क्रमबद्ध क्रम की ओर नहीं गिनना चाहिए और इसकी तुलना अगले वर्ण पर करनी चाहिए। utf8mb4_unicode_ci
इनको ठीक से संभालता है।
गैर-लैटिन भाषाओं में, जैसे एशियाई भाषाएं या विभिन्न वर्णमाला वाली भाषाएं, यूनिकोड छंटाई और सरलीकृत छंटाई के बीच बहुत अधिक अंतर हो सकता है utf8mb4_general_ci
। utf8mb4_general_ci
इस्तेमाल की जाने वाली भाषा पर उपयुक्तता निर्भर करेगी। कुछ भाषाओं के लिए, यह काफी अपर्याप्त होगा।
आपको क्या उपयोग करना चाहिए?
अब लगभग निश्चित रूप से उपयोग करने का कोई कारण utf8mb4_general_ci
नहीं है, क्योंकि हमने उस बिंदु को पीछे छोड़ दिया है जहां सीपीयू की गति काफी कम है कि प्रदर्शन अंतर महत्वपूर्ण होगा। आपका डेटाबेस लगभग निश्चित रूप से अन्य बाधाओं से सीमित होगा।
अतीत में, कुछ लोगों ने उपयोग करने की सिफारिश की, utf8mb4_general_ci
जब सटीक छंटाई प्रदर्शन लागत को सही ठहराने के लिए पर्याप्त महत्वपूर्ण होने जा रही थी। आज, वह प्रदर्शन लागत सभी गायब हो गई है, और डेवलपर्स अंतर्राष्ट्रीयकरण को अधिक गंभीरता से मान रहे हैं।
एक तर्क दिया जाना चाहिए कि यदि सटीकता की तुलना में गति आपके लिए अधिक महत्वपूर्ण है, तो आप किसी भी तरह की छँटाई नहीं कर सकते हैं। यदि आपको सटीक होने की आवश्यकता नहीं है, तो एक एल्गोरिथ्म को तेज़ बनाना तुच्छ है। तो, utf8mb4_general_ci
एक समझौता है जो शायद गति कारणों के लिए आवश्यक नहीं है और शायद सटीकता के कारणों के लिए भी उपयुक्त नहीं है।
एक और चीज़ जो मैं जोड़ूंगा वह यह है कि यदि आप जानते हैं कि आपका आवेदन केवल अंग्रेजी भाषा का समर्थन करता है, तो भी इसे लोगों के नामों से निपटने की आवश्यकता हो सकती है, जिसमें अक्सर अन्य भाषाओं में उपयोग किए जाने वाले वर्ण शामिल हो सकते हैं जिसमें सही ढंग से छांटना महत्वपूर्ण है । सब कुछ के लिए यूनिकोड नियमों का उपयोग करने से मन की शांति जोड़ने में मदद मिलती है कि बहुत ही स्मार्ट यूनिकोड लोगों ने छँटाई के काम को ठीक से करने के लिए बहुत मेहनत की है।
भागों का क्या मतलब है
सबसे पहले, ci
के लिए है केस-संवेदी छंटाई और तुलना। इसका मतलब यह है कि यह पाठ डेटा के लिए उपयुक्त है, और मामला महत्वपूर्ण नहीं है। cs
पाठ डेटा के लिए अन्य प्रकार के टकराव (केस-संवेदी) हैं जहां मामला महत्वपूर्ण है, और bin
, जहां एन्कोडिंग को मिलान करने की आवश्यकता है, बिट के लिए बिट, जो उन क्षेत्रों के लिए उपयुक्त है जो वास्तव में एन्कोडेड बाइनरी डेटा हैं (उदाहरण के लिए, सहित) Base64)। केस-सेंसिटिव सॉर्टिंग कुछ अजीब परिणाम देता है और केस-सेंसिटिव तुलना डुप्लिकेट वैल्यू के परिणामस्वरूप केवल लेटर केस में भिन्न हो सकती है, इसलिए केस-सेंसिटिव कोलाज पाठ डेटा के पक्ष में गिर रहे हैं - यदि मामला आपके लिए महत्वपूर्ण है, तो अन्यथा अनुचित विराम चिह्न और इसलिए शायद यह भी महत्वपूर्ण है, और एक द्विआधारी टकराव अधिक उपयुक्त हो सकता है।
अगला, unicode
या general
विशिष्ट छंटाई और तुलना नियमों का संदर्भ देता है - विशेष रूप से, जिस तरह से पाठ को सामान्य या तुलना किया जाता है। Utf8mb4 वर्ण एन्कोडिंग के लिए नियमों के कई अलग-अलग सेट हैं, दो unicode
और general
एक विशिष्ट एक के बजाय सभी संभव भाषाओं में अच्छी तरह से काम करने का प्रयास करते हैं। नियमों के इन दो सेटों के बीच अंतर इस उत्तर का विषय है। ध्यान दें कि unicode
यूनिकोड 4.0 से नियमों का उपयोग करता है। MySQL के हाल के संस्करणों में unicode_520
यूनिकोड 5.2 से नियमों का उपयोग करते हुए नियमों को जोड़ा गया है , और 0900
यूनिकोड 9.0 से नियमों का उपयोग करके "यूनिकोड_" भाग को छोड़ना है।
और अंत में, utf8mb4
निश्चित रूप से आंतरिक रूप से इस्तेमाल किया जाने वाला चरित्र एन्कोडिंग है। इस उत्तर में मैं केवल यूनिकोड आधारित एन्कोडिंग के बारे में बात कर रहा हूँ।
utf8_general_ci
: यह बस काम नहीं करता है। यह पचास साल पहले के ASCII के बुरे दिनों के पुराने दिनों की बदनामी है। यूसीडी से फोल्डकेस मैप के बिना यूनिकोड केस-असंवेदनशील मिलान नहीं किया जा सकता है। उदाहरण के लिए, "ςος" में तीन अलग-अलग संयोग हैं; या "TSCHüẞ" का निचला भाग "tschü," कैसे है, लेकिन "tschü t" का अपरकेस "TSCHÜSS" है। आप सही हो सकते हैं, या आप तेज हो सकते हैं। इसलिए आपको इसका उपयोग करना चाहिए utf8_unicode_ci
, क्योंकि यदि आप शुद्धता की परवाह नहीं करते हैं, तो इसे अनंत रूप से तेज बनाने के लिए तुच्छ है।
"か" == "が"
या "ǽ" == "æ"
। छँटाई के लिए यह समझ में आता है, लेकिन समानता के माध्यम से चयन करने या अद्वितीय सूचकांकों के साथ काम करने पर आश्चर्य हो सकता है - Bugs.mysql.com/bug.php?id=16526
utf8mb4
है केवल सही विकल्प । utf8
आप के साथ कुछ MySQL में ही अटक कर रहे हैं, UTF8 के 3-बाइट वेरिएंट जो केवल MySQL (और MariaDB) जानते हैं कि क्या करना है। बाकी दुनिया UTF8 का उपयोग कर रही है, जिसमें प्रति वर्ण 4 बाइट्स हो सकते हैं । MySQL ने अपने होमब्रॉव एन्कोडिंग का गलत इस्तेमाल किया utf8
और पिछड़े अनुकूलता को नहीं तोड़ने के लिए, उन्हें अब वास्तविक UTF8 के रूप में संदर्भित करना होगा utf8mb4
।
मुझे पता है कि का उपयोग कर के बीच प्रदर्शन अंतर नहीं है क्या चाहता था utf8_general_ci
और utf8_unicode_ci
है, लेकिन मैं इंटरनेट पर सूचीबद्ध किसी भी मानक नहीं मिला, तो मैं अपने आप को मानक बनाने का फैसला किया।
मैंने 500,000 पंक्तियों के साथ एक बहुत ही सरल तालिका बनाई:
CREATE TABLE test(
ID INT(11) DEFAULT NULL,
Description VARCHAR(20) DEFAULT NULL
)
ENGINE = INNODB
CHARACTER SET utf8
COLLATE utf8_general_ci;
फिर मैंने इसे संग्रहीत प्रक्रिया चलाकर यादृच्छिक डेटा से भर दिया:
CREATE PROCEDURE randomizer()
BEGIN
DECLARE i INT DEFAULT 0;
DECLARE random CHAR(20) ;
theloop: loop
SET random = CONV(FLOOR(RAND() * 99999999999999), 20, 36);
INSERT INTO test VALUES (i+1, random);
SET i=i+1;
IF i = 500000 THEN
LEAVE theloop;
END IF;
END LOOP theloop;
END
तब मैं बेंचमार्क सरल करने के लिए संग्रहित प्रक्रियाओं निम्नलिखित बनाया SELECT
, SELECT
साथ LIKE
, और (छँटाई SELECT
के साथ ORDER BY
):
CREATE PROCEDURE benchmark_simple_select()
BEGIN
DECLARE i INT DEFAULT 0;
theloop: loop
SELECT *
FROM test
WHERE Description = 'test' COLLATE utf8_general_ci;
SET i = i + 1;
IF i = 30 THEN
LEAVE theloop;
END IF;
END LOOP theloop;
END;
CREATE PROCEDURE benchmark_select_like()
BEGIN
DECLARE i INT DEFAULT 0;
theloop: loop
SELECT *
FROM test
WHERE Description LIKE '%test' COLLATE utf8_general_ci;
SET i = i + 1;
IF i = 30 THEN
LEAVE theloop;
END IF;
END LOOP theloop;
END;
CREATE PROCEDURE benchmark_order_by()
BEGIN
DECLARE i INT DEFAULT 0;
theloop: loop
SELECT *
FROM test
WHERE ID > FLOOR(1 + RAND() * (400000 - 1))
ORDER BY Description COLLATE utf8_general_ci LIMIT 1000;
SET i = i + 1;
IF i = 10 THEN
LEAVE theloop;
END IF;
END LOOP theloop;
END;
utf8_general_ci
टकराव के ऊपर संग्रहीत प्रक्रियाओं में उपयोग किया जाता है, लेकिन निश्चित रूप से परीक्षणों के दौरान मैंने दोनों का उपयोग किया utf8_general_ci
और utf8_unicode_ci
।
मैंने प्रत्येक संग्रह के लिए 5 बार (प्रत्येक के लिए 5 बार utf8_general_ci
और 5 बार utf8_unicode_ci
) प्रत्येक संग्रहीत प्रक्रिया को बुलाया और फिर औसत मूल्यों की गणना की।
मेरे परिणाम हैं:
benchmark_simple_select()
utf8_general_ci
: 9,957 एमएस utf8_unicode_ci
: 10,271 मि इस बेंचमार्क का उपयोग 3.2% utf8_unicode_ci
की तुलना में धीमा है utf8_general_ci
।
benchmark_select_like()
utf8_general_ci
: 11,441 मि utf8_unicode_ci
: 12,811 मि इस बेंचमार्क का उपयोग 12% utf8_unicode_ci
की तुलना में धीमा है utf8_general_ci
।
benchmark_order_by()
utf8_general_ci
: 11,944 एमएस utf8_unicode_ci
: 12,887 एमएस इस बेंचमार्क का उपयोग 7.9% utf8_unicode_ci
की तुलना में धीमा है utf8_general_ci
।
utf8_general_ci
केवल उपयोग करने लायक होने के लिए बहुत कम है।
CONV(FLOOR(RAND() * 99999999999999), 20, 36)
केवल ASCII उत्पन्न करता है, और कोलाज के एल्गोरिदम द्वारा संसाधित होने के लिए कोई यूनिकोड वर्ण नहीं है। 2) Description = 'test' COLLATE ...
और Description LIKE 'test%' COLLATE ...
केवल एक ही स्ट्रिंग ("परीक्षण") को रनटाइम पर संसाधित करते हैं, क्या वे नहीं? 3) वास्तविक ऐप्स में, ऑर्डर करने में उपयोग किए जाने वाले कॉलम को संभवतः अनुक्रमित किया जाएगा, और वास्तविक गैर-एएससीआईआई पाठ के साथ अलग-अलग टकरावों पर अनुक्रमण गति भिन्न हो सकती है।
यह पोस्ट बहुत अच्छी तरह से इसका वर्णन करता है।
संक्षेप में: utf8_unicode_ci यूनिकोड मानकों के अनुसार यूनिकोड कोलाज एल्गोरिथ्म का उपयोग करता है, जबकि utf8_general_ci एक अधिक सरल सॉर्ट क्रम है जिसके परिणामस्वरूप "कम सटीक" सॉर्टिंग परिणाम मिलते हैं।
utf8_unicode_ci
और दूसरे को दिखावा मौजूद नहीं है।
utf8_general_ci
लिए हो सकता है
Mysql मैनुअल, यूनिकोड कैरेक्टर सेट्स अनुभाग देखें:
किसी भी यूनिकोड वर्ण सेट के लिए, _general_ci collation का उपयोग करके किए गए ऑपरेशन _unicode_ci टकराव की तुलना में तेज़ होते हैं। उदाहरण के लिए, utf8_general_ci collation के लिए तुलनाएं तेज़ हैं, लेकिन utf8_unicode_ci की तुलना की तुलना में थोड़ा कम सही हैं। इसका कारण यह है कि utf8_unicode_ci विस्तार जैसे मैपिंग का समर्थन करता है; वह है, जब एक वर्ण अन्य वर्णों के संयोजन के बराबर होता है। उदाहरण के लिए, जर्मन और कुछ अन्य भाषाओं में "," "ss" के बराबर है। utf8_unicode_ci भी संकुचन और आग्नेय वर्णों का समर्थन करता है। utf8_general_ci एक विरासत टकराव है जो विस्तार, संकुचन या अज्ञानतापूर्ण पात्रों का समर्थन नहीं करता है। यह पात्रों के बीच केवल एक-से-एक तुलना कर सकता है।
इसलिए संक्षेप में, utf_general_ci utf_unicode_ci की तुलना में एक छोटे और कम सही (मानक के अनुसार) सेट का उपयोग करता है जो पूरे मानक को लागू करना चाहिए । सामान्य _ci सेट तेज़ होगा क्योंकि करने के लिए कम संगणना है।
utf8_unicode_ci
और छोटी गाड़ी टूटी संस्करण का नाटक मौजूद नहीं है।
0
और 1
, एक बूल नहीं है। :) ईजी को एक बाउंडिंग बॉक्स में जियो पॉइंट्स का चयन करना 'पॉइंट्स पास' का एक अनुमान है जो बिंदु और संदर्भ बिंदु के बीच की दूरी की गणना करने और उस पर फ़िल्टर करने के रूप में उतना अच्छा नहीं है। लेकिन दोनों एक अनुमान हैं और वास्तव में, पूर्ण शुद्धता ज्यादातर प्राप्त करने योग्य नहीं है। देखें समुद्र तट विरोधाभास और आईईईई 754
1/3
संक्षिप्त शब्दों में:
यदि आपको बेहतर क्रमबद्ध क्रम की आवश्यकता है - उपयोग utf8_unicode_ci
(यह पसंदीदा तरीका है),
लेकिन अगर आप प्रदर्शन में पूरी तरह से रुचि रखते हैं - उपयोग करें utf8_general_ci
, लेकिन यह जान लें कि यह थोड़ा पुराना है।
प्रदर्शन के मामले में अंतर बहुत मामूली है।
जैसा कि हम यहां पढ़ सकते हैं ( पीटर गुलटेज़न ) पॉलिशिंग लेटर "Ł" (एल विद स्ट्रोक - html esc :)Ł
(लोअर केस: "ł" - एचटीएम esc:) को छाँटने / तुलना करने पर अंतर है ł
- हमारी निम्नलिखित धारणा है:
utf8_polish_ci Ł greater than L and less than M
utf8_unicode_ci Ł greater than L and less than M
utf8_unicode_520_ci Ł equal to L
utf8_general_ci Ł greater than Z
पोलिश भाषा में पत्र Ł
के बाद L
और पहले पत्र है M
। इस कोडिंग में से कोई भी बेहतर या बदतर नहीं है - यह आपकी आवश्यकताओं पर निर्भर करता है।
छँटाई और वर्ण मिलान के दो बड़े अंतर हैं:
छँटाई :
utf8mb4_general_ci
सभी उच्चारणों को हटाता है और एक-एक करके छांटता है जिससे गलत प्रकार के परिणाम बन सकते हैं।utf8mb4_unicode_ci
सही तरह से।चरित्र मिलान
वे किरदारों से अलग तरह से मेल खाते हैं।
उदाहरण के लिए, utf8mb4_unicode_ci
आप में है i != ı
, लेकिन utf8mb4_general_ci
यह धारण करता है ı=i
।
उदाहरण के लिए, कल्पना करें कि आपके पास एक पंक्ति है name="Yılmaz"
। फिर
select id from users where name='Yilmaz';
पंक्ति वापसी होगी अगर मोरचा है utf8mb4_general_ci
, लेकिन अगर यह साथ collocated है utf8mb4_unicode_ci
यह होगा नहीं पंक्ति वापसी!
दूसरी ओर हम उस राशि पर a=ª
और ß=ss
में utf8mb4_unicode_ci
जो में ऐसा नहीं है utf8mb4_general_ci
। तो कल्पना कीजिए कि आपके पास एक पंक्ति है name="ªßi"
, फिर
select id from users where name='assi';
यदि पंक्तिबद्धता है तो पंक्ति लौटाएगी utf8mb4_unicode_ci
, लेकिन यदि पंक्तिबद्धता को सेट किया गया है तो पंक्ति नहीं लौटेगी utf8mb4_general_ci
।
प्रत्येक कोलोकेशन के मैचों की पूरी सूची यहां मिल सकती है ।
इस पोस्ट के अनुसार, utf8mb4_general_ci के उपयोग के दौरान utf8mb4_unicode_ci: https://www.percona.com/blog/2019/02/27-charset-and-collation-settings-impact के उपयोग से MySQL 5.7 पर काफी बड़ा प्रदर्शन लाभ होता है। ऑन-mysql प्रदर्शन /