मेरे पास एक एप्लिकेशन है जो केवल समानता पर चयन करेगा, और मुझे लगता है कि मुझे btree सूचकांक पर हैश इंडेक्स का उपयोग करना चाहिए। मेरे निराशा, हैश सूचकांकों में से अधिकांश MyISAM या InnoDB पर समर्थित नहीं हैं। उसके साथ क्या है?
मेरे पास एक एप्लिकेशन है जो केवल समानता पर चयन करेगा, और मुझे लगता है कि मुझे btree सूचकांक पर हैश इंडेक्स का उपयोग करना चाहिए। मेरे निराशा, हैश सूचकांकों में से अधिकांश MyISAM या InnoDB पर समर्थित नहीं हैं। उसके साथ क्या है?
जवाबों:
कई डेटाबेस हैश आधारित अनुक्रमणिका का समर्थन नहीं करते सब पर ।
हैश तालिका के कुशल होने के लिए आपको उन पंक्तियों की संख्या जानने की आवश्यकता है जो मौजूद होने की संभावना है अन्यथा आधार हैश तालिका बहुत बड़ी होगी (कई खाली प्रविष्टियाँ, अंतरिक्ष को बर्बाद करना और संभावित डिस्क IO) या बहुत छोटा अर्थ अप्रत्यक्ष रूप से अक्सर उपयोग किया जाता है (संभवतः अप्रत्यक्ष के कई स्तर, या इससे भी बदतर अगर हैश कार्यान्वयन एकल-स्तर है जो आप रिकॉर्ड की एक उचित संख्या पर एक रेखीय खोज कर सकते हैं) जिस बिंदु पर चीजें शायद अधिक कुशल नहीं हैं तो एक पेड़ आधारित है फिर भी सूचकांक।
इसलिए आम तौर पर उपयोगी होने के लिए (यानी आमतौर पर विकल्प से बेहतर) सूचकांक को कभी-कभी फिर से बनाने की आवश्यकता होती है क्योंकि डेटा बढ़ता है (और सिकुड़ता है) जो एक महत्वपूर्ण आंतरायिक ओवरहेड जोड़ सकता है। यह आमतौर पर मेमोरी आधारित तालिकाओं के साथ ठीक है क्योंकि पुनर्निर्माण शायद बहुत तेज होने वाला है (जैसा कि डेटा हमेशा रैम में रहने वाला है और किसी भी मामले में बड़े पैमाने पर होने की संभावना नहीं है), लेकिन डिस्क पर एक बड़े सूचकांक का पुनर्निर्माण करना एक है बहुत भारी ऑपरेशन (और IIRC mySQL लाइव इंडेक्स रीबिल्ड का समर्थन नहीं करता है इसलिए ऑपरेशन के दौरान टेबल लॉक रखता है)।
इसलिए हैश इंडेक्स का उपयोग मेमोरी टेबल में किया जाता है क्योंकि वे आम तौर पर बेहतर प्रदर्शन करने वाले होते हैं, लेकिन डिस्क आधारित टेबल उनका समर्थन नहीं करते हैं क्योंकि वे बोनस नहीं होने के लिए एक बाधा हो सकते हैं। बंद हैश अनुक्रमणिका के लिए कुछ भी निश्चित रूप से डिस्क आधारित तालिकाओं के लिए उपलब्ध कराया जा रहा है, इसमें कोई शक नहीं कुछ डेटाबेसों कर सुविधा का समर्थन है, लेकिन शायद वे ISAM में लागू नहीं कर रहे हैं / देखरेख के रूप में InnoDB टेबल सुविधा लायक जोड़ने (के रूप में विचार नहीं करते लिखने और बनाए रखने के लिए अतिरिक्त कोड उन कुछ परिस्थितियों में लाभ के लायक नहीं है कि यह एक महत्वपूर्ण अंतर बनाता है)। शायद अगर आप दृढ़ता से असहमत हैं तो आप उनसे बात कर सकते हैं और सुविधा के कार्यान्वयन के लिए एक अच्छा मामला बना सकते हैं।
यदि आप बड़े स्ट्रिंग्स को अनुक्रमित कर रहे हैं तो अपना स्वयं का छद्म हैश इंडेक्स लागू करें (मूल्य के एक हैश के साथ-साथ वास्तविक मूल्य और स्तंभ का अनुक्रमण करके) काम कर सकता है, लेकिन यह निश्चित रूप से बड़े स्ट्रिंग्स के लिए अधिक कुशल है (जहां हैश मान की गणना करना और इस मान से ट्री इंडेक्स की खोज करना हमेशा तेज होने की संभावना है, तो तुलना के लिए बड़े मूल्यों का उपयोग करके ट्री इंडेक्स की खोज करना, और उपयोग किया जाने वाला अतिरिक्त भंडारण महत्वपूर्ण नहीं है) इसलिए लागू करने से पहले कुछ प्रदर्शन विश्लेषण करें। यह उत्पादन में है।
संबंधित नोट पर, आपको PostgreSQL डॉक्स से इंडेक्स प्रकारों पर चर्चा दिलचस्प लग सकती है। यह डॉक्स के हाल के संस्करणों में मौजूद नहीं है (बाद में अनुकूलन के कारण, मैं इसे ले लेता हूं), लेकिन टेकअवे MySQL के लिए समान हो सकता है (और हैश इंडेक्स केवल हीप टेबल के लिए उपयोग किया जाता है):
http://www.postgresql.org/docs/8.1/static/indexes-types.html
नोट: परीक्षण ने बी-ट्री इंडेक्स की तुलना में कोई बेहतर प्रदर्शन करने के लिए PostgreSQL के हैश इंडेक्स को दिखाया है, और हैश इंडेक्स के लिए इंडेक्स आकार और निर्माण समय बहुत खराब है। इसके अलावा, हैश इंडेक्स ऑपरेशन वर्तमान में वाल-लॉग नहीं हैं, इसलिए हैश इंडेक्स को डेटाबेस क्रैश के बाद REINDEX के साथ पुनर्निर्माण करना पड़ सकता है। इन कारणों से, हैश इंडेक्स का उपयोग वर्तमान में हतोत्साहित किया जाता है। इसी तरह, आर-ट्री इंडेक्स को जीएसटी इंडेक्स के बराबर संचालन की तुलना में कोई प्रदर्शन लाभ नहीं लगता है। हैश इंडेक्स की तरह, वे वाल-लॉग नहीं हैं और डेटाबेस क्रैश के बाद रीइन्डेक्सिंग की आवश्यकता हो सकती है। जबकि हैश इंडेक्स के साथ समस्याओं को अंततः ठीक किया जा सकता है, यह संभावना है कि भविष्य के रिलीज में आर-ट्री इंडेक्स प्रकार को सेवानिवृत्त किया जाएगा। उपयोगकर्ताओं को उन अनुप्रयोगों को माइग्रेट करने के लिए प्रोत्साहित किया जाता है जो आर-ट्री इंडेक्स का उपयोग जीएसटी इंडेक्स में करते हैं।
फिर से, यह (अप्रचलित संस्करण) PostgreSQL- विशिष्ट है, लेकिन यह संकेत देना चाहिए कि "प्राकृतिक" सूचकांक प्रकार आवश्यक रूप से इष्टतम प्रदर्शन नहीं करेगा।
यहाँ कुछ दिलचस्प है:
पुस्तक MySQL 5.0 प्रमाणन अध्ययन गाइड , पृष्ठ 433, धारा 29.5.1 के अनुसार
मेमोरी इंजन डिफ़ॉल्ट इंडेक्सिंग एल्गोरिथ्म द्वारा एचएएसएच का उपयोग करता है।
हंसने के लिए, मैंने MySQL 5.5.12 में HASH का उपयोग करके एक प्राथमिक कुंजी के साथ एक InnoDB तालिका और एक MyISAM तालिका बनाने की कोशिश की
mysql> use test
Database changed
mysql> create table rolando (num int not null, primary key (num) using hash);
Query OK, 0 rows affected (0.11 sec)
mysql> show create table rolando\G
*************************** 1. row ***************************
Table: rolando
Create Table: CREATE TABLE `rolando` (
`num` int(11) NOT NULL,
PRIMARY KEY (`num`) USING HASH
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> create table rolando2 (num int not null, primary key (num) using hash) engine=MyISAM;
Query OK, 0 rows affected (0.05 sec)
mysql> show create table rolando2\G
*************************** 1. row ***************************
Table: rolando2
Create Table: CREATE TABLE `rolando2` (
`num` int(11) NOT NULL,
PRIMARY KEY (`num`) USING HASH
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
MySQL ने शिकायत नहीं की।
अद्यतन करें
बुरी खबर !!! मैंने SHOW INDEXES FROM का उपयोग किया। यह कहते हैं कि सूचकांक BTREE है।
बनाएँ सूचकांक वाक्य रचना MySQL पृष्ठ कहा गया है कि केवल स्मृति और NDB भंडारण इंजन HASH सूचकांक समायोजित कर सकते हैं।
mysql> show indexes from rolando;
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| rolando | 0 | PRIMARY | 1 | num | A | 0 | NULL | NULL | | BTREE | | |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
mysql> show indexes from rolando2;
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| rolando2 | 0 | PRIMARY | 1 | num | A | 0 | NULL | NULL | | BTREE | | |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
mysql> create table rolando3 (num int not null, primary key (num)) ENGINE=MEMORY;
Query OK, 0 rows affected (0.03 sec)
mysql> show create table rolando3\G
*************************** 1. row ***************************
Table: rolando3
Create Table: CREATE TABLE `rolando3` (
`num` int(11) NOT NULL,
PRIMARY KEY (`num`)
) ENGINE=MEMORY DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> show indexes from rolando3;
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| rolando3 | 0 | PRIMARY | 1 | num | NULL | 0 | NULL | NULL | | HASH | | |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
कुछ लोगों ने हैश एल्गोरिथ्म का अनुकरण करने के लिए पुस्तक " हाई परफॉर्मेंस मायक्यूसी: ऑप्टिमाइजेशन, बैकअप, प्रतिकृति और अधिक " के पेज 102-105 में इस विचार का पालन किया ।
पृष्ठ 105 इस त्वरित और गंदे एल्गोरिथ्म को पसंद करता है जो मुझे पसंद है:
SELECT CONV(RIGHT(MD5('whatever value you want'),16),16,10) AS HASH64;
किसी भी तालिका में इसके लिए एक कॉलम बनाएं और इस मान को अनुक्रमित करें।
कोशिश तो करो !!!
बीट्री एकल पंक्ति देखने के लिए हैश की तुलना में बहुत धीमी नहीं है। चूँकि BTree बहुत ही कुशल रेंज क्वेश्चन प्रदान करता है, क्यों कि BTree के अलावा किसी और चीज़ से परेशान हों।
MySQL BTree ब्लॉकों को कैशिंग करने का एक बहुत अच्छा काम करता है, इसलिए BTree- आधारित क्वेरी को शायद ही कभी I / O करना पड़ता है, जो किसी भी क्वेरी में सबसे बड़ा समय उपभोक्ता है।