2011-08-18 9 views
8

मैं इस तरह एक प्रश्न है:सही अनुक्रमण का उपयोग करते समय OR ऑपरेटर

SELECT fields FROM table 
WHERE field1='something' OR field2='something' 
OR field3='something' OR field4='something' 

क्या इस प्रश्न के लिए सूचकांक इस तरह के एक मेज पर सही तरीका क्या होगा?

इस तरह की एक क्वेरी चलाने के लिए एक पूरा सेकंड लेता है! मेरे पास उन सभी फ़ील्ड के साथ 1 इंडेक्स है, इसलिए मुझे लगता है कि MySQL कुछ ऐसा करेगा:

इंडेक्स में प्रत्येक पंक्ति के माध्यम से जाएं यह सोचें: फ़ील्ड 1 कुछ है? फील्ड 2 के बारे में कैसे? फ़ील्ड 3? फ़ील्ड 4? ठीक है, नहीं, अगली पंक्ति पर जाएं।

उत्तर

15

आप गलत समझते हैं कि इंडेक्स कैसे काम करते हैं।

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

अब अगर मैं आपको उन सभी लोगों को ढूंढने के लिए कहता हूं जिनके अंतिम नाम "स्मिथ" हैं या जिसका पहला नाम "जॉन" है, तो आप स्मिथ को आसानी से पहले ढूंढ सकते हैं, लेकिन इससे आपको यह पता लगाने में मदद नहीं मिलती है जॉन्स। वे अभी भी पूरे पुस्तक में बिखरे हुए हैं और आपको उन्हें कठिन तरीके से खोजना है।

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

अपने मूल प्रश्न पर वापस जाएं।

इस क्वेरी के लिए ऐसी तालिका को इंडेक्स करने का सही तरीका क्या होगा?

प्रत्येक कॉलम पर एक अलग, सिंगल-कॉलम अनुक्रमणिका बनाएं। इन इंडेक्स में से एक दूसरों की तुलना में बेहतर विकल्प होगा, MySQL के estimation of how many I/O operations के आधार पर इंडेक्स का उपयोग होने पर किया जाएगा। MySQL के

आधुनिक संस्करण भी index merging के बारे में कुछ स्मार्ट है, तो क्वेरी किसी तालिका में एक से अधिक सूचकांक का उपयोग कर सकते हैं, और फिर परिणाम विलय करने के लिए प्रयास करें। अन्यथा MySQL किसी दिए गए प्रश्न में प्रति तालिका एक अनुक्रमणिका का उपयोग करने के लिए सीमित है।

एक और चाल है कि बहुत से लोग सफलतापूर्वक उपयोग करते हैं, आपके प्रत्येक अनुक्रमित कॉलम (जो संबंधित सूचकांक का उपयोग करना चाहिए) और फिर UNION परिणामों के लिए एक अलग क्वेरी करना है।

SELECT fields FROM table WHERE field1='something' 
UNION 
SELECT fields FROM table WHERE field2='something' 
UNION 
SELECT fields FROM table WHERE field3='something' 
UNION 
SELECT fields FROM table WHERE field4='something' 

एक अंतिम अवलोकन: यदि आप पाते हैं अपने आप को एक ही 'something' चार भर में क्षेत्रों के लिए खोज, आप अगर सभी चार क्षेत्रों वास्तव में एक ही बात कर रहे हैं पर पुनर्विचार करना चाहिए, और आप उस violates First Normal form with repeating groups एक मेज को डिजाइन करने का दोषी हो। यदि ऐसा है, तो फ़ील्ड 4 के माध्यम से फ़ील्ड 1 बच्चे तालिका में एक कॉलम में है।तो यह एक बहुत सूचकांक और क्वेरी के लिए आसान हो जाता है:

SELECT fields from table INNER JOIN child_table ON table.pk = child_table.fk 
WHERE child_table.field = 'something' 
0

पिछली टिप्पणी के अलावा: mysql/PostgreSQL जैसे कुछ RDMS सूचकांक विलय अगर अनुकूलक मानना ​​है कि यह अच्छा विचार है उपयोग कर सकते हैं। तो आप प्रत्येक फ़ील्ड के लिए अलग-अलग इंडेक्स बना सकते हैं या फ़ील्ड 1, फ़ील्ड 2 और फील्ड 3, फ़ील्ड 4 जैसी कुछ समग्र इंडेक्स बना सकते हैं। अंत में, आपको कई अलग-अलग समाधानों का प्रयास करना चाहिए और सर्वोत्तम व्याख्या योजना के साथ चयन करना चाहिए।

संबंधित मुद्दे

 संबंधित मुद्दे