2009-04-28 10 views
34

मैं (उदाहरण के लिए) एक सूचकांक मिल गया है:क्या एकल कॉलम के लिए एक मल्टी-कॉलम इंडेक्स भी काम करता है?

CREATE INDEX someIndex ON orders (customer, date); 

इस सूचकांक केवल प्रश्नों जहां ग्राहक और तारीख उपयोग किया जाता है या यह बहुत इस तरह की एक एकल-स्तंभ के लिए क्वेरी में तेजी लाने करता है में तेजी लाने करता है?

SELECT * FROM orders WHERE customer > 33; 

मैं SQLite का उपयोग कर रहा हूं।


यदि उत्तर हाँ है, तो प्रति तालिका एक से अधिक अनुक्रमणिका क्यों बनाना संभव है?


फिर भी एक और सवाल: कैसे बहुत तेजी से एक संयुक्त सूचकांक दो separat अनुक्रमित से की जाती है जब आप कोई क्वेरी में दोनों स्तंभ का उपयोग करें?

उत्तर

32

marc_s अपने पहले प्रश्न का सही उत्तर है। एक बहु कुंजी सूचकांक में पहली कुंजी एक ही कुंजी इंडेक्स की तरह काम कर सकती है लेकिन बाद की कुंजियां नहीं होंगी।

समग्र सूचकांक आपके डेटा पर निर्भर करता है और आप अपनी अनुक्रमणिका और क्वेरी को कैसे व्यवस्थित करते हैं, लेकिन यह आमतौर पर महत्वपूर्ण है। इंडेक्स अनिवार्य रूप से स्क्लाइट को खेतों पर बाइनरी खोज करने की अनुमति देते हैं।

उदाहरण आप दे दी है यदि आप क्वेरी भाग गया का उपयोग करना:

SELECT * from orders where customer > 33 && date > 99 

SQLite पहले पूरे मेज पर एक द्विआधारी खोज का उपयोग कर सभी परिणाम प्राप्त जहां ग्राहक> 33. तो यह एक द्विआधारी खोज ही पर क्या होगा उन परिणामों की तारीख की तलाश> 99.

यदि आपने ग्राहक और दिनांक पर दो अलग-अलग इंडेक्स के साथ एक ही प्रश्न किया है, तो स्क्लिट को पूरे टेबल को दो बार खोजना होगा, पहले ग्राहक के लिए और फिर तारीख के लिए।

तो आप कितनी गति वृद्धि देखेंगे इस पर निर्भर करता है कि आप अपनी क्वेरी के संबंध में अपनी अनुक्रमणिका कैसे बनाते हैं। आदर्श रूप से, आपकी अनुक्रमणिका और आपकी क्वेरी में पहला क्षेत्र वह होना चाहिए जो सबसे संभावित मैचों को समाप्त कर देता है क्योंकि दूसरी खोज को काम करने की मात्रा को बहुत कम करके बहुत तेज गति वृद्धि होगी।

अधिक जानकारी के लिए इस देखें: http://www.sqlite.org/optoverview.html

+2

SQLite किसी सूचकांक के दूसरे कॉलम का उपयोग नहीं करेगा यदि पहला कॉलम असमानता अभिव्यक्ति था (उदाहरण के लिए ग्राहक> 33)। (अधिकांश डेटाबेस इंजन, कठिन होगा)। – vmatyi

+1

यदि आप दो अलग-अलग सूचकांक बनाते हैं, तो उनमें से केवल एक का उपयोग किया जाएगा, दूसरी अभिव्यक्ति का मूल्यांकन पहले द्वारा उत्पन्न परिणाम सेट पर किया जाएगा। (ओरेकल पर, यह _could_ दो इंडेक्स खोज निष्पादित करता है और परिणाम सेट को छेड़छाड़ करता है, अगर ऑप्टिमाइज़ेशन लागत आधारित है और कुछ मानदंड मिलते हैं, लेकिन यह एक दुर्लभ मामला है)। – vmatyi

5

मुझे यकीन है कि यह काम करेगा, हाँ - यह एमएस एसक्यूएल सर्वर में वैसे भी करता है।

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

मार्क

+0

धन्यवाद, यही वह जगह है जहां मुझे यकीन नहीं था। मैं उस मामले में दो अलग-अलग इंडेक्स तैयार करूंगा। –

3

मैं आमतौर पर संयुक्त डेटा के माध्यम से सॉर्ट करने के लिए अनुक्रमणिका का उपयोग मैं पृष्ठ पर अंक लगाना या अनुरोध "streamily" करना चाहते हैं।

ग्राहक मानते हैं कि एक से अधिक ऑर्डर कर सकते हैं .. और 11 से 11 ग्राहक मौजूद हैं और प्रति ग्राहक कई आदेश यादृच्छिक क्रम में डाले गए हैं। मैं तारीख के बाद ग्राहक संख्या के आधार पर एक क्वेरी को सॉर्ट करना चाहता हूं। आपको आईडी फ़ील्ड को क्रमबद्ध करने के लिए आखिरी बार सेट करना चाहिए जहां एक ग्राहक की कई समान तिथियां होती हैं (भले ही वह कभी नहीं हो)।एक क्रमबद्ध क्वेरी की

sqlite> CREATE INDEX customer_asc_date_asc_index_asc ON orders 
      (customer ASC, date ASC, id ASC); 

प्राप्त पेज 1 (10 आइटम तक सीमित):

sqlite> SELECT id, customer, date FROM orders 
      ORDER BY customer ASC, date ASC, id ASC LIMIT 10; 

2653|1|1303828585 
2520|1|1303828713 
2583|1|1303829785 
1828|1|1303830446 
1756|1|1303830540 
1761|1|1303831506 
2442|1|1303831705 
2523|1|1303833761 
2160|1|1303835195 
2645|1|1303837524 

अगले पृष्ठ प्राप्त करें:

sqlite> SELECT id, customer, date FROM orders WHERE 
      (customer = 1 AND date = 1303837524 and id > 2645) OR 
      (customer = 1 AND date > 1303837524) OR 
      (customer > 1) 
      ORDER BY customer ASC, date ASC, id ASC LIMIT 10; 

2515|1|1303837914 
2370|1|1303839573 
1898|1|1303840317 
1546|1|1303842312 
1889|1|1303843243 
2439|1|1303843699 
2167|1|1303849376 
1544|1|1303850494 
2247|1|1303850869 
2108|1|1303853285 

और इसी तरह ...

इंडेक्स को स्थानांतरित करने से सर्वर साइड इंडेक्स स्कैनिंग कम हो जाती है जब आप अन्यथा एक LIMIT के साथ एक क्वेरी ऑफसेट का उपयोग करते हैं। क्वेरी समय लंबे समय तक हो जाता है और ड्राइव की तलाश कठिन उच्च ऑफसेट चला जाता है। इस विधि का उपयोग करना इसे समाप्त करता है।

इस विधि का उपयोग करके सलाह दी जाती है कि क्या आप बाद में डेटा में शामिल होने की योजना बनाते हैं लेकिन केवल प्रति अनुरोध डेटा के सीमित सेट की आवश्यकता है। बड़े टेबल के लिए मेमोरी ओवरहेड को कम करने के लिए ऊपर वर्णित एक SUBSELECT के खिलाफ शामिल हों।

+0

यह भी अनावश्यक सर्वर साइड आदेश समय को खत्म करने में मदद करता है ... आप उपयोग करना ** datetime थे (तिथि, 'unixepoch', 'स्थानीयसमय') ** ** एक वापसी स्तंभ के रूप में की तारीख ** के बजाय .. यह विश्वासपूर्वक होगा सीमित रहो। मेरा मानना ​​है कि यह वैसे भी होगा - इंजन पर निर्भर करता है। – whardier

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