बहुरंगी सूचकांक और प्रदर्शन


31

मेरे पास एक बहुरंगी सूचकांक वाली एक तालिका है, और मुझे प्रश्नों पर अधिकतम प्रदर्शन प्राप्त करने के लिए अनुक्रमित की उचित छंटाई के बारे में संदेह है।

परिदृश्य:

  • PostgreSQL 8.4, लगभग एक मिलियन पंक्तियों वाली तालिका

  • कॉलम c1 में मान लगभग 100 भिन्न मान हो सकते हैं । हम मान सकते हैं कि मूल्य समान रूप से वितरित किए गए हैं, इसलिए हमारे पास हर संभव मूल्य के लिए लगभग 10000 पंक्तियाँ हैं।

  • कॉलम c2 में 1000 विभिन्न मूल्य हो सकते हैं । हमारे पास हर संभव मूल्य के लिए 1000 पंक्तियाँ हैं।

डेटा खोजते समय, स्थिति में हमेशा इन दो स्तंभों के लिए मूल्य शामिल होते हैं, इसलिए तालिका में c1 और c2 के संयोजन का एक बहुरंगी सूचकांक होता है। यदि आपने फ़िल्टरिंग के लिए सिर्फ एक कॉलम का उपयोग करके प्रश्न किए हैं, तो मैंने एक बहुरंगी सूचकांक में कॉलम को ठीक से ऑर्डर करने के महत्व के बारे में पढ़ा है । हमारे परिदृश्य में ऐसा नहीं है।

मेरा सवाल यह है:

इस तथ्य को देखते हुए कि फिल्टर में से एक डेटा के बहुत छोटे सेट का चयन करता है, क्या मैं प्रदर्शन में सुधार कर सकता हूं यदि पहला इंडेक्स सबसे अधिक चयनात्मक है (जो एक छोटे सेट की अनुमति देता है)? मैंने इस प्रश्न पर तब तक कभी विचार नहीं किया, जब तक कि मैंने संदर्भित लेख के ग्राफिक्स को नहीं देखा:

यहां छवि विवरण दर्ज करें

बहुरंगी अनुक्रमणिकाओं के बारे में संदर्भित लेख से ली गई छवि ।

फ़िल्टरिंग के लिए क्वेरीज़ दो स्तंभों से मानों का उपयोग करती हैं। मेरे पास फ़िल्टर करने के लिए सिर्फ एक कॉलम का उपयोग करने के लिए कोई प्रश्न नहीं है। वे सब के सब कर रहे हैं: WHERE c1=@ParameterA AND c2=@ParameterB। इस तरह की शर्तें भी हैं:WHERE c1 = "abc" AND c2 LIKE "ab%"

जवाबों:


36

उत्तर

चूंकि आप वेबसाइट का संदर्भ लेते हैं use-the-index-luke.com, अध्याय पर विचार करें:

इंडेक्स, ल्यूक> द व्हेयर क्लॉज> सर्चिंग फॉर रेंज्स> ग्रेटर, कम एंड बेटविन

इसका एक उदाहरण है जो आपकी स्थिति से पूरी तरह मेल खाता है (दो-कॉलम इंडेक्स, एक को समानता के लिए परीक्षण किया जाता है , दूसरे को रेंज के लिए ), बताते हैं (उन अच्छे इंडेक्स ग्राफिक्स के साथ) क्यों @ ypercube की सलाह सटीक है और इसे पूरा करता है:

Rule of thumb: index for equality first  then for ranges.

सिर्फ एक कॉलम के लिए भी अच्छा है?

सिर्फ एक कॉलम पर प्रश्नों के लिए क्या करना स्पष्ट प्रतीत होता है। इन संबंधित प्रश्नों के तहत अधिक विवरण और बेंचमार्क:

कम चयनात्मक स्तंभ पहले?

इसके अलावा, क्या होगा यदि आपके पास दोनों स्तंभों के लिए केवल समानता की स्थिति है ?

इससे कोई फर्क नहीं पड़ता । कॉलम को पहले रखें जो स्वयं की स्थितियों को प्राप्त करने की अधिक संभावना है, जो वास्तव में मायने रखता है।

इस डेमो पर विचार करें, या इसे स्वयं पुन: उत्पन्न करें। मैं 100k पंक्तियों के साथ दो स्तंभों की एक सरल तालिका बनाता हूं। बहुत से एक कुछ , के साथ एक दूसरे को बहुत विशिष्ट मानों की:

CREATE TEMP TABLE t AS
SELECT (random() * 10000)::int AS lots
     , (random() * 4)::int     AS few
FROM generate_series (1, 100000);

DELETE FROM t WHERE random() > 0.9;  -- create some dead tuples, more "real-life"

ANALYZE t;

SELECT count(distinct lots)   -- 9999
     , count(distinct few)    --    5
FROM   t;

प्रश्न:

SELECT *
FROM   t
WHERE  lots = 2345
AND    few = 2;

EXPLAIN ANALYZE आउटपुट (कैशिंग प्रभाव को बाहर करने के लिए सर्वश्रेष्ठ 10):

T पर स्कैन स्कैन (लागत = 0.00..5840.84 पंक्तियाँ = २ चौड़ाई = ()
               (वास्तविक समय = 5.646..15.535 पंक्तियों = 2 छोरों = 1)
  फ़िल्टर: (बहुत से = 2345) और (कुछ = 2))
  बफ़र्स: स्थानीय हिट = 443
कुल रनटाइम: 15.557 एमएस

अनुक्रमणिका जोड़ें, फिर से लिखें:

CREATE INDEX t_lf_idx ON t(lots, few);
T_lf_idx को t (लागत = 0.00..3.76 पंक्तियों = 2 चौड़ाई = 8) का उपयोग करके सूचकांक स्कैन करें
                                (वास्तविक समय = 0.008..0.011 पंक्तियों = 2 छोरों = 1)
  सूचकांक कंडोम: (बहुत से = २३४५) और (कुछ = २))
  बफ़र्स: स्थानीय हिट = 4
कुल रनटाइम: 0.027 एमएस

अन्य सूचकांक जोड़ें, फिर से लिखें:

DROP INDEX t_lf_idx;
CREATE INDEX t_fl_idx  ON t(few, lots);
T_fl_idx को t (लागत = 0.00..3.74 पंक्तियों = 2 चौड़ाई = 8) का उपयोग करके सूचकांक स्कैन करें
                                (वास्तविक समय = 0.007..0.011 पंक्तियों = 2 छोरों = 1)
  सूचकांक कंडोम: ((कुछ = 2) और (लॉट = 2345))
  बफ़र्स: स्थानीय हिट = 4
कुल रनटाइम: 0.027 एमएस

क्या यह भी सूचकांक में 3 (या अधिक) कॉलम के लिए मामला है?
hayd

@hayd: निश्चित नहीं कि "यह" किसको संदर्भित करता है। आप एक नया प्रश्न पूछ सकते हैं । आप संदर्भ के लिए इसे हमेशा संदर्भित कर सकते हैं। (और वापस लिंक करने के लिए यहां एक टिप्पणी छोड़ें।)
इरविन ब्रांडस्टैटर

यदि "इंडेक्स डेफिनिशन" का मतलब इंडेक्स डेफिनेशन मैटर का ऑर्डर करना है, तो इंडेक्स डेफिनेशन में 2 से ज्यादा कॉलम हैं
हाईड

@hayd: सबसे महत्वपूर्ण बिंदु: एक btree सूचकांक प्रमुख सूचकांक अभिव्यक्तियों पर समानता की स्थिति वाले प्रश्नों के लिए अच्छा है । उनमें से आदेश ज्यादातर अप्रासंगिक है। कई अन्य विवरण जो एक टिप्पणी में फिट नहीं होंगे ...
एरविन ब्रांडस्टैटर

धन्यवाद, मैं एक सुसंगत प्रश्न लिखूंगा और इसे लिंक करूंगा।
4

11

यदि, जैसा कि आप कहते हैं, इन 2 कॉलमों को शामिल करने वाले प्रश्न, दोनों स्तंभों की सभी समानता की जाँच हैं, जैसे:

WHERE c1=@ParameterA AND c2=@ParameterB

इससे परेशान न हों। मुझे संदेह है कि कोई अंतर होगा और यदि कोई है, तो यह नगण्य होगा। आप हमेशा अपने डेटा और अपने सर्वर सेटिंग्स के साथ निश्चित रूप से परीक्षण कर सकते हैं। एक DBMS के विभिन्न संस्करणों अनुकूलन के बारे में थोड़ा अलग तरीके से व्यवहार कर सकते हैं।

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

अगर मुझे दो में से एक आदेश चुनना था, तो मैं पहले कम चुनिंदा कॉलम रखना चाहूंगा । स्तंभों के साथ एक तालिका पर विचार करें yearऔर month। यह अधिक संभावना है कि आपको एक WHERE year = 2000शर्त या एक की आवश्यकता WHERE year BETWEEN 2000 AND 2013है WHERE (year, month) BETWEEN (1999, 6) AND (2000, 5)

प्रकार की एक क्वेरी WHERE month = 7 GROUP BY yearसुनिश्चित की जा सकती है (जुलाई में पैदा हुए लोग खोजें), लेकिन अक्सर कम होगा। यह निश्चित रूप से आपकी तालिका में संग्रहीत वास्तविक डेटा पर निर्भर करता है। अब के लिए एक आदेश चुनें, (c1, c2)और आप हमेशा बाद में एक और सूचकांक जोड़ सकते हैं (c2, c1)


ओपी की टिप्पणी के बाद अपडेट करें :

इस तरह की शर्तें भी हैं: WHERE c1 = 'abc' AND c2 LIKE 'ab%'

इस प्रकार की क्वेरी यदि c2स्तंभ पर बिल्कुल श्रेणी की स्थिति है और उसे एक (c1, c2)इंडेक्स की आवश्यकता होगी । यदि आपके पास भी रिवर्स प्रकार के प्रश्न हैं:

WHERE c2 = 'abc' AND c1 LIKE 'ab%'

तब यह अच्छा होगा यदि आपके पास एक (c2, c1)सूचकांक भी हो।

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