मैं MySQL तालिकाओं में सूचकांक कैसे जोड़ूं?


407

मुझे डेटा की लगभग 150,000 पंक्तियों के साथ एक बहुत बड़ी MySQL तालिका मिली है। वर्तमान में, जब मैं कोशिश करता हूं और दौड़ता हूं

SELECT * FROM table WHERE id = '1';

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

SELECT * FROM table WHERE product_id = '1';

इस क्षेत्र को पहले अनुक्रमित नहीं किया गया था; हालाँकि, मैंने एक जोड़ा है, इसलिए mysql अब फ़ील्ड को अनुक्रमित करता है, लेकिन जब मैं उपरोक्त क्वेरी को चलाने का प्रयास करता हूं, तो यह बहुत धीमी गति से चलता है। एक एक्सक्लूसिव क्वेरी से पता चलता है कि जब मैंने पहले ही एक जोड़ा है, तो product_id फ़ील्ड के लिए कोई इंडेक्स नहीं है, और परिणामस्वरूप क्वेरी किसी भी पंक्ति को वापस करने के लिए 20 मिनट से 30 मिनट तक ले जाती है।

मेरे पूर्ण परिणाम हैं:

| id | select_type | table | type | possible_keys| key  | key_len | ref  | rows  | Extra       |
+----+-------------+-------+------+--------------+------+---------+------+-------+------------------+
|  1 | SIMPLE      | table | ALL  | NULL         | NULL | NULL    | NULL |157211 | Using where |
+----+-------------+-------+------+--------------+------+---------+------+-------+------------------+

यह नोट करना मददगार हो सकता है कि मैंने अभी-अभी देखा है और ID फ़ील्ड को INT के रूप में संग्रहीत किया गया है जबकि PRODUCT_ID फ़ील्ड को VCHCHAR के रूप में संग्रहीत किया गया है। क्या यह समस्या का स्रोत हो सकता है?


1
क्या आप पूर्ण EXPLAINपरिणाम पोस्ट कर सकते हैं ? क्या आप निश्चित हैं कि कोई सूचकांक नहीं है ? या वहाँ सूचकांक है, लेकिन MySQL का उपयोग करने के लिए नहीं चुन रहा है?
वोटडेइसीपल जू

169
एक बड़ी तालिका में 150,000,000 रिकॉर्ड होंगे। एक बहुत बड़ी तालिका में 15,000,000,000 रिकॉर्ड हैं। औसत आकार की एक तालिका में 150,000 हैं। आगामी संदर्भ के लिए।
usumoio

4
विदित हो कि 'OR' MySql इंडेक्स का उपयोग नहीं कर सकता है। मेरे पास 3 या के साथ एक क्वेरी थी। प्रत्येक ने एक सूचकांक बनाया, और 15ms में भाग गया, सभी ने मिलकर 25sec और मध्यांतर के बीच लिया। इसलिए मैंने 3 प्रश्न किए और उन्हें एक साथ जोड़ा, इसमें 500.000 पंक्तियों पर 15ms भी लगे।
लीफ नेलैंड

उस डेटा प्रकार पर विचार करें जिसे आप संग्रहीत कर रहे हैं। आपके डेटा प्रकार की तुलना आप कर रहे हैं के आधार पर प्रदर्शन बदल सकता है। जैसा कि आपने कहा कि PRODUCT_ID एक VARCHAR डेटा प्रकार है, इसे एक INT में बदलने का प्रयास करें और कॉलम को इंडेक्स करें।
गिलेबर्डीम

जवाबों:


606
ALTER TABLE `table` ADD INDEX `product_id_index` (`product_id`)

कभी तुलना integerकरने के लिए stringsMySQL में। यदि idहै int, तो उद्धरण निकालें।


मैंने उस सटीक SQL का उपयोग करके पहले ही सूचकांक जोड़ दिया है, लेकिन ऐसा लगता है कि इसे डेटा में "लागू नहीं" किया गया है और EXPLAIN क्वेरी से पता चलता है कि क्षेत्र के लिए कोई सूचकांक नहीं है।
माइकल

1
SHOW CREATE TABLE वाले इंडेक्स को चेक करने के लिए केयर करें, या आपने पहले ही ऐसा कर लिया है?
2

33
इंडेक्स जोड़ा गया है या नहीं, यह SHOW INDEXES FROM YOURTABLE जांचने के लिए dev.mysql.com/doc/refman/5.0/en/show-index.html का उपयोग करें
तिमु हुओवेंन

6
आज मुझे सटीक समस्या @Michael का वर्णन था, और समाधान "कभी भी पूर्णांक की तुलना mysql में तार से करने की नहीं थी।" धन्यवाद।
user12345

@Wrikken मैंने अपना इंडेक्स जोड़ा और अपनी कमांड SHOW INDEXES फ्रॉम योरटेबल का इस्तेमाल किया। यह पता चलता है, लेकिन मुझे नहीं लगता कि इसका उपयोग मेरी तालिका को क्वेरी करते समय किया जाता है। क्या मुझे इंडेक्स का उपयोग करते समय चयन क्वेरी को बदलना होगा?
सीएसएस

147
ALTER TABLE TABLE_NAME ADD INDEX (COLUMN_NAME);

96
MySQL में, आप का उपयोग करता है, तो ALTER TABLE tbl ADD INDEX (col)बजाय ALTER TABLE tbl ADD INDEX col (col), तो का उपयोग कर ALTER TABLE tbl ADD INDEX (col)एक बार से अधिक नामित सूचकांक जोड़ने रखेंगे col_2, col_3... हर बार। जबकि ALTER TABLE tbl ADD INDEX col (col)2 वें समय का उपयोग करते हुए देंगे ERROR 1061 (42000): Duplicate key name 'col'
अभिषेक ओझा

82

आप इस सिंटैक्स का उपयोग किसी इंडेक्स को जोड़ने और इंडेक्स (HASH या BTREE) को नियंत्रित करने के लिए कर सकते हैं।

create index your_index_name on your_table_name(your_column_name) using HASH;
or
create index your_index_name on your_table_name(your_column_name) using BTREE;

आप यहाँ BTREE और HASH इंडेक्स के बीच अंतर के बारे में जान सकते हैं: http://dev.mysql.com/doc/refman/5.5/en/index-btree-hash.html


1
जब मैं शो इंडेक्स का उपयोग कर रहा हूं, तो हैश btree में परिवर्तित हो गया।
आरएन कुशवाहा

1
यदि मैं कोई निर्दिष्ट नहीं करता हूं, तो हश और ब्रीरी से डिफ़ॉल्ट क्या होगा?
भावुक माथुर

2
@RNKushwaha क्योंकि InnoDB और MyIsam HASH, AFAIK का समर्थन नहीं करते हैं, केवल मेमोरी और NDB स्टोरेज इंजन इसका समर्थन करते हैं
Hieu Vo

60

यह ध्यान देने योग्य है कि कई फ़ील्ड इंडेक्स आपके क्वेरी प्रदर्शन में काफी सुधार कर सकते हैं। इसलिए उपरोक्त उदाहरण में हम मानते हैं कि ProductID लुकअप का एकमात्र क्षेत्र है, लेकिन ProductID = 1 और श्रेणी = 7 को कहने के लिए क्वेरी थी तो एक मल्टीपल कॉलम इंडेक्स मदद करता है। यह निम्नलिखित के साथ प्राप्त किया जाता है:

ALTER TABLE `table` ADD INDEX `index_name` (`col1`,`col2`)

इसके अतिरिक्त सूचकांक को क्वेरी फ़ील्ड के क्रम से मेल खाना चाहिए। मेरे विस्तारित उदाहरण में इंडेक्स होना चाहिए (ProductID, श्रेणी) अन्य तरीके से नहीं।


1
अच्छा, स्पष्ट रूप से नामकरण सूचकांक आसान उलट करने की अनुमति देता है।
सैम बेरी

क्या आप स्रोत का उद्धरण दे सकते हैं the index should match the order of the query fields?
बिस्वास मिश्रा

58

दो प्रकार के सूचकांक जोड़े जा सकते हैं: जब आप एक प्राथमिक कुंजी परिभाषित करते हैं, तो MySQL डिफ़ॉल्ट रूप से इसे सूचकांक के रूप में ले जाएगा।

व्याख्या

सूचकांक के रूप में प्राथमिक कुंजी

विचार करें कि आपके पास एक tbl_studentमेज है और आप student_idप्राथमिक कुंजी के रूप में चाहते हैं :

ALTER TABLE `tbl_student` ADD PRIMARY KEY (`student_id`)

उपरोक्त कथन एक प्राथमिक कुंजी जोड़ता है, जिसका अर्थ है कि अनुक्रमित मान अद्वितीय होना चाहिए और NULL नहीं हो सकता है।

सूचकांक नाम निर्दिष्ट करें

ALTER TABLE `tbl_student` ADD INDEX student_index (`student_id`)

उपरोक्त कथन से एक साधारण सूचकांक बनेगा student_index नाम के ।

अद्वितीय सूचकांक बनाएँ

ALTER TABLE `tbl_student` ADD UNIQUE student_unique_index (`student_id`)

यहाँ, student_unique_index छात्र_ को निर्दिष्ट किया गया इंडेक्स नाम है और एक इंडेक्स बनाता है जिसके लिए मान अद्वितीय होने चाहिए (यहां नल को स्वीकार किया जा सकता है)।

पूर्ण विकल्प

ALTER TABLE `tbl_student` ADD FULLTEXT student_fulltext_index (`student_id`)

ऊपर दिए गए स्टेटमेंट से फुलटेक्स्ट इंडेक्स नाम बनेगा student_fulltext_index , जिसके लिए आपको MyISAM मैसकल इंजन की आवश्यकता होगी।

इंडेक्स कैसे निकालें?

DROP INDEX `student_index` ON `tbl_student`

उपलब्ध इंडेक्स की जांच कैसे करें?

SHOW INDEX FROM `tbl_student`

17

आप कहते हैं कि आपके पास एक सूचकांक है, व्याख्या अन्यथा कहती है। हालांकि, यदि आप वास्तव में करते हैं, तो यह है कि कैसे जारी रखें:

यदि आपके पास स्तंभ पर एक सूचकांक है, और MySQL इसका उपयोग नहीं करने का निर्णय लेता है, तो यह इस कारण से हो सकता है:

  1. MySQL के प्रश्न में एक और सूचकांक है जिसका उपयोग करने के लिए अधिक उपयुक्त है, और यह केवल एक का उपयोग कर सकता है। समाधान आमतौर पर कई स्तंभों को फैलाने वाला एक सूचकांक होता है यदि उनकी पुनर्प्राप्ति की सामान्य विधि एक से अधिक स्तंभों के मान से होती है।
  2. MySQL तय करता है कि कई मिलान पंक्तियाँ हैं, और सोचता है कि एक टेबस्कैन शायद अधिक तेज़ है। अगर ऐसा नहीं है, तो कभी-कभी ANALYZE TABLEमदद मिलती है।
  3. अधिक जटिल प्रश्नों में, यह क्वेरी-प्लान में अत्यंत बुद्धिमान विचार-विमर्श के आधार पर इसका उपयोग नहीं करने का निर्णय करता है कि किसी कारण से आपकी वर्तमान आवश्यकताओं के अनुरूप नहीं है।

(2) या (3) के मामले में, आप सूचकांक के संकेत सूचकांक द्वारा MySQL को सूचकांक का उपयोग करने में सहवास कर सकते हैं , लेकिन यदि आप करते हैं, तो यह निर्धारित करने के लिए कुछ परीक्षण चलाएं कि क्या यह वास्तव में सूचकांक का उपयोग करने के लिए प्रदर्शन में सुधार करता है जैसा कि आप संकेत देते हैं। ।

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