2011-10-22 13 views
5

मैं उस तालिका के लिए आवश्यक न्यूनतम इंडेक्स के माध्यम से सोचने के तरीके पर मार्गदर्शन प्राप्त कर रहा हूं जिसमें आप कॉलम के उसी सेट पर प्रश्नों के विभिन्न संयोजन कर रहे हैं। आदर्श रूप से, आपका उत्तर इस विशिष्ट उदाहरण से अंगूठे के कुछ नियमों को सार करेगा (यदि यह संभव है)।डीबी सूचकांक कॉलम के एक ही सेट के प्रश्नों के एकाधिक संयोजन के लिए उपयोग करने के लिए?

इस बुलेट की गई सूची तीन अलग-अलग क्वेरी की स्थिति सामान्य रूप से मेरे मेज पर प्रदर्शन का प्रतिनिधित्व करता है:

  • कहां race_type =? और recordable_type =? और सक्रिय =?
  • जहां race_type =? और recordable_id =? और recordable_type =? और सक्रिय =?
  • जहां उपयोगकर्ता_आईडी =? और race_type =? और recordable_id =? और recordable_type =? और सक्रिय =?

नोट: user_id (पूर्णांक), race_type (varchar), recordable_id (पूर्णांक), recordable_type (varchar), सक्रिय (बुलियन)

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

यदि मुझे सर्वोत्तम उत्तर प्राप्त करने के लिए अधिक जानकारी प्रदान करने की आवश्यकता है, तो कृपया मुझे बताएं।

+0

कृपया वर्तमान तालिका परिभाषा दिखाएं (तालिका बनाएं ...)। क्या user_id प्राथमिक कुंजी का हिस्सा है? – Devart

उत्तर

8

यदि आपकी शर्तें पदानुक्रमित हैं (जैसे आपके उदाहरण में) आप संयुक्त सूचकांक का उपयोग कर सकते हैं। डीबीएमएस को एक साथ कई इंडेक्स के साथ काम करने में परेशानी है। हालांकि यह संभव है और वे इस तरह की स्थिति से बाहर निकलने का प्रयास करते हैं।

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

की हर जगह के लिए एक सूचकांक निर्दिष्ट करके बाहर शुरू करते हैं:

index1 (race_type, recordable_type, active) 
index2 (race_type, recordable_id, recordable_type, active) 
index3 (user_id, race_type, recordable_id, recordable_type, active) 

सामान्य तौर पर आप प्रमुखता आरोही करके अपने आदेश अनुकूलन कर सकते हैं। कार्डिनालिटी संभावित मानों की संख्या है कि आपके डेटासेट में कॉलम में होगा। आपके उदाहरण में active एक बूलियन है। (कृपया ध्यान दें कि boolean में केवल दो मान हो सकते हैं वास्तव में महत्वपूर्ण नहीं है। यह intहो सकता है यदि आपको पता है कि इसमें केवल दो मान होंगे: 0 और 1)।

आपके active फ़ील्ड की निम्न कार्डिनालिटी का अर्थ है कि एक ही लुकअप के साथ हम संभावित रिकॉर्ड्स के आधे को समाप्त कर सकते हैं (कोर्स के अपने डेटासेट के आधार पर)। इस कदम के बाद अपने पहले सूचकांक देखने की तरह होगा:

index1 (active, race_type, recordable_type) 

प्रमुखता इसके अलावा आप क्षेत्रों के बीच किसी भी तार्किक पदानुक्रम के लिए ध्यान देना चाहिए। इन नामों का अर्थ जानने के बिना मैं अंगूठे के नियम के रूप में अनुमान लगाता हूं कि कुछ दौड़ प्रकार का अपना रिकॉर्डबेल होगा। - यह एक से अधिक रेस प्रकार के पाठ्यक्रम के साथ उपयोग किए जाने वाले रिकॉर्ड करने योग्य होने की संभावना को खत्म नहीं करेगा, लेकिन आपको एक ऑर्डर चुनना होगा और यह अधिक तार्किक लगता है। - इसलिए हम race_type, recordable_type ऑर्डर का उपयोग करेंगे।

अब चलिए दूसरी अनुक्रमणिका में ले लें। आपने यहां recordable_id पेश किया है। अपने डेटासेट को जानने के बिना मैं सुरक्षित रूप से मान सकता हूं कि recordable_id की कार्डिनालिटी रिकॉर्ड करने योग्य_टाइप की तुलना में बड़ी होगी। दूसरे शब्दों में प्रकारों की तुलना में अधिक आईडी होगी। इसके अलावा मुझे टाइप और आईडी (एक से कई लोगों की तरह गंध) के बीच पदानुक्रम पर संदेह है। तो चलिए इसे इस प्रकार टाइप करें:

index2 (active, race_type, recordable_type, recordable_id) 

अब यह एक अन्य महत्वपूर्ण कोण पर ध्यान देने का समय है। आपके डीबी को संशोधित करते समय इंडेक्स की अपनी एचडीडी (अनिवार्य रूप से मुक्त) और सीपीयू चक्र पर अपनी लागत होती है। किसी भी इंडेक्स का सबसेट बाएं से दाएं से शुरू किया जा सकता है। index2 अनिवार्य रूप से index1 है क्योंकि यह index1 + recordable_id है, इसलिए आप इसे से छुटकारा पा सकते हैं और एक के साथ समाप्त हो सकते हैं।

user_id के साथ आता है।एक आईडी फ़ील्ड के रूप में यह उच्च कार्डिनालिटी (कई संभावित मान) सुझाता है, लेकिन ध्यान दें कि यह नियम नहीं है कि "बाद में दायर की गई कार्डिनिटी उच्च होगी"। हमने खेतों के बीच पदानुक्रम जैसे संबंधों की मदद करने के लिए एक बीकन के रूप में कार्डिनिटी का उपयोग किया। (और सूचकांक आकार घटाना)।

क्या user_id व्यक्तिगत प्रतिभागी को इंगित करता है जिस डेटा पर हम देख रहे हैं (कई संभावनाएं)? या यह वह ग्राहक है जिसने डेटा अपलोड किया (बहुत कम संभावनाएं)? यह कहना मुश्किल है। तुम बस अपने मौजूदा index2 से संलग्न कर सकते हैं और आप एक ही सूचकांक कि तीनों secnarios में इस्तेमाल किया जा सकता है के साथ खत्म हो जाएगा:

search_index (active, race_type, recordable_type, recordable_id, user_id) 

... या यह इस scanario के लिए एक दूसरे सूचकांक होने के लायक हो सकता है ..

आपका प्रश्न विशेष है क्योंकि आप अपने क्लॉज में केवल = का उपयोग करते हैं। AND (race_type = 1 OR race_type=8) जैसे > या < का उल्लेख नहीं करने के लिए कई अन्य विचार हैं। इसके अलावा यदि आप ORDER BY का उपयोग करते हैं जिसे आपके द्वारा उपयोग किए जाने वाले इंडेक्स में शामिल किया जा सकता है।

+0

+1 कुछ अच्छी इंडेक्सिंग रणनीतियों का अच्छा स्पष्टीकरण – ChandlerPelhams

+0

* सामान्य रूप से आप अपने आदेश को बढ़ते कार्डिनिटी द्वारा अनुकूलित कर सकते हैं (...) आपके सक्रिय क्षेत्र की कम कार्डिनालिटी का मतलब है कि एक ही लुकअप के साथ हम संभावित रिकॉर्ड्स के आधे को खत्म कर सकते हैं * - यह कैसा है? कार्डिनालिटी जितना अधिक होगा, हर समानता जांच से अधिक मूल्य समाप्त हो जाएंगे। – Tgr

+0

@Tgr आप सही हैं अगर आप कुछ गैर-अनुक्रमित संचालन के साथ इक्विटी चेक का संयोजन कर रहे हैं। हालांकि, निम्न से उच्च कार्डिनालिटी द्वारा ऑर्डर करने से फ़ील्ड के बीच प्राकृतिक पदानुक्रम (निर्भरता) हो सकती है, और अगर आपके प्रश्न इंडेक्स के भीतर काम कर रहे हैं तो इसमें कोई वास्तविक कमी नहीं है। - फिर फिर, ये केवल सामान्य संकेतक हैं, यह सब डेटासेट पर निर्भर करता है। – vbence

2

imho

alter table your_table 
add index (race_type, recordable_type, active, user_id, recordable_id); 
// watch-out the max length allowed for an index 

आम पाया कॉलम race_type, recordable_type, active,
हैं और मैं एक सूचकांक के निर्माण के लिए सभी 5 कॉलम सभी खोज पैटर्न फिट होगा द्वारा लगता है।

मुझे बताएं कि प्रस्ताव में अच्छी तरह से काम नहीं करता है

3

प्रथम चरण प्रश्नों आप अनुकूलन के लिए विचार कर रहे हैं पर EXPLAIN उपयोग करने के लिए है तो कृपया। MySQL explain महत्वपूर्ण जानकारी लौटाएगा जिस पर क्वेरी को पूरा करने के लिए सूचकांक का उपयोग किया जाएगा, और आपको अपने प्रश्नों को अनुकूलित करने में मदद मिलेगी।

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

आपको लुकअप टेबल से जोड़ने वाले आईडी में अपने वर्चर्स कॉलम को बदलने पर भी विचार करना चाहिए। यह अपने डेटाबेस के लिए कुछ अतिरिक्त स्कीमा जोड़ना होगा, लेकिन आप निम्न लाभ मिलेंगे:

  1. क्या तुमने कभी स्तंभ का मान बदलने की जरूरत है, तो आप केवल एक पंक्ति, बनाम हजारों बदलना होगा।

  2. सभी कॉलम जो आप इंडेक्स के लिए विचार कर रहे हैं वे संख्यात्मक होंगे, जो प्रकृति द्वारा वर्चर्स की तुलना में तेज़ी से होगी, और अधिकतम सूचकांक लंबाई सीमा तक पहुंचने से पहले अधिक ओवरहेड देगी।

1

अपने मामले उचित सूचकांक में user_id + race_type + recordable_id + recordable_type + सक्रिय किसी भी क्रम में है। वह तो आसान था। आपने सामान्य दृष्टिकोण के बारे में पूछा? यही पर है।

इंडेक्स को समझना बहुत महत्वपूर्ण है।थीम जटिल है, इसलिए मेरा जवाब बड़ा है। मैं docs से, मेरे उत्तर और exmaples पढ़ने का सुझाव देते हैं।

कहां, ऑर्डर और समूह में उपयोग किए गए सभी कॉलम इंडेक्स होना चाहिए। माइस्क्ल इंडेक्सिंग के लिए बाइनरी पेड़ का उपयोग करता है। इसका मतलब है कि, सूचकांक का उपयोग अंतराल के बिना बाएं से दाएं भाग के आंशिक रूप से किया जा सकता है। जैसे हमारे पास कंपाउंड इंडेक्स है (ए, बी)। तो: WHERE a = 1 AND b = 1 - पूर्ण अनुक्रमणिका का उपयोग करता है, WHERE a = 1 - इंडेक्स का आधा उपयोग करता है - बाइनरी पेड़ इंडेक्स का उपयोग बाएं से आंशिक रूप से किया जा सकता है, WHERE b = 1 - पूर्णस्कैन का उपयोग करता है (कोई अनुक्रमणिका का उपयोग नहीं किया जा सकता है), WHERE (a = 0 OR a = 1) AND b = 1 - पूर्णस्कैन का उपयोग करता है (mysql कई खोज शाखाओं का समर्थन नहीं करता है)।

कुछ प्रश्न इंडेक्स का उपयोग नहीं कर सकते हैं। जैसे "OR" कथन के साथ प्रश्न (बाइनरी पेड़ इंडेक्स संवेदी हैं)। या कॉल की तरह '% ...%' - बाइनरी इंडेक्स का उपयोग केवल बाएं से आंशिक रूप से किया जा सकता है।

उचित इंडेक्स लागू करने का अल्गोरिथम: "WHERE" में उपयोग किए जाने वाले सभी अद्वितीय कॉलम नाम प्राप्त करें। ऑर्डर और समूह से सभी अद्वितीय कॉलम नामों को क्वेरी में दिखाई देने के तरीके से लें और "WHERE" (दाएं से जोड़ें) से फ़ील्ड में जोड़ें। सूचकांक को कम करने के लिए, इसलिए वे अभी भी mysql द्वारा उपयोग किया जा सकता है।

आपके पास अपने प्रश्नों में कोई ऑर्डर नहीं है, लेकिन ऑर्डर को इंडेक्स की भी आवश्यकता है। इसलिए मैंने आपका उदाहरण थोड़ा और जटिल बना दिया:

  • जहां race_type =? और recordable_type =? और सक्रिय =? Race_type द्वारा आदेश
  • जहां race_type =? और recordable_id =? और recordable_type =? और सक्रिय =? दिनांक डीईएससी द्वारा आदेश,
  • जहां उपयोगकर्ता_आईडी =? और race_type =? और recordable_id =? और recordable_type =? और सक्रिय =?

    1. इंडेक्स से "कहाँ" द्वारा तारीख एएससी आदेश: "race_type + recordable_type + सक्रिय", "race_type + recordble_id + recordable_type + सक्रिय" और "user_id + race_type + recordable_id + recordable_type सक्रिय +"। प्रकार से

    2. जोड़ा जा रहा है अनुक्रमित:

      • race_type + recordable_type + सक्रिय + race_type
      • race_type + recordble_id + recordable_type + सक्रिय + तारीख
      • user_id + race_type + recordable_id + recordable_type + सक्रिय + तारीख
    3. कम करें अनुक्रमित:

      • recordable_type + सक्रिय + race_type (छँटाई के लिए अंत में दो कॉलम स्थानांतरित, लेकिन त्यागा "तिथि")
      • recordable_type + सक्रिय + race_type + recordble_id + तिथि ("कहां" और "आदेश" के लिए दोनों का उपयोग किया)
      • कोई बदलाव नहीं (हम "तिथि" के बाद "user_id" ले जाएँ और इस एक में पिछले सूचकांक में शामिल करने की कोशिश नहीं कर सकते हैं)

देखें, सूचकांक # 1 # 2 सूचकांक में शामिल किया गया है, तो सूचकांक # 1 दूर फेंक दें।

  • recordable_type + सक्रिय + race_type + recordble_id + तारीख
  • user_id + race_type + recordable_id + recordable_type + सक्रिय + तारीख

के लिए मत भूलना: अंत में हम एक के इंडेक्स है अद्यतन और हटाए गए प्रश्नों में उपयोग किए गए algorythm कॉलम द्वारा इंडेक्स।

1

माइस्क्ल बाएं अधिकांश इंडेक्स का उपयोग करता है, इसका मतलब है कि, यदि सूचकांक जटिल है (इसमें एक कॉलम अधिक है) क्वेरी इंडेक्स कॉलम सूची में बाएं से दाएं इंडेक्स से ट्रैक्टर को ट्रैवर करता है, यदि शून्य है (क्वेरी कहां है या जॉइन स्टेटमेंट नहीं है आगे इंडेक्स कॉलम का उपयोग नहीं किया जाएगा)

त्वरित टिप, कुछ संभावित मूल्यों वाले फ़ील्ड के लिए आप क्वेरी लिख सकते हैं, यह सभी सकारात्मक मूल्यों से अधिक है जो इसका मतलब है कि अभी भी इंडेक्स के अधिक कॉलम का उपयोग किया जा सकता है (उदा। , जहां (सक्रिय = 0 या सक्रिय = 1) और ...)

0

आपके पास इन क्षेत्रों में WHERE स्थितियां हैं: user_id, race_type, recordable_id, recordable_type और सक्रिय। उनमें से कुछ को स्थिति में निर्दिष्ट दोहराया जा सकता है।

मैं उन्हें एक के बाद रास्ते में आदेश दिया: तालिका एक और अनुक्रमित या प्राथमिक कुंजी है

ALTER TABLE table_name 
    ADD INDEX IX_table_name (race_type, recordable_type, active, recordable_id, user_id); 

हैं, तो एक प्रयोग सूचकांक खंड जोड़ें:

* WHERE race_type = ? AND recordable_type = ? AND active = ? 
* WHERE race_type = ? AND recordable_type = ? AND active = ? AND recordable_id = ? 
* WHERE race_type = ? AND recordable_type = ? AND active = ? AND recordable_id = ? AND user_id = ? 

यह हमें एक समग्र सूचकांक बनाने की अनुमति देता नामित सूचकांक का उपयोग करने के लिए:

SELECT * FROM table_name USE INDEX IX_table_name 
WHERE 
    race_type = ? AND recordable_type = ? AND active = ? AND recordable_id = ? AND user_id = ? 
संबंधित मुद्दे