सीमा के साथ धीमी गति से आदेश


11

मेरे पास यह प्रश्न है:

SELECT * 
FROM location 
WHERE to_tsvector('simple',unaccent2("city"))
   @@ to_tsquery('simple',unaccent2('wroclaw')) 
order by displaycount

मैं इससे खुश हूं:

"Sort  (cost=3842.56..3847.12 rows=1826 width=123) (actual time=1.915..2.084 rows=1307 loops=1)"
"  Sort Key: displaycount"
"  Sort Method: quicksort  Memory: 206kB"
"  ->  Bitmap Heap Scan on location  (cost=34.40..3743.64 rows=1826 width=123) (actual time=0.788..1.208 rows=1307 loops=1)"
"        Recheck Cond: (to_tsvector('simple'::regconfig, unaccent2((city)::text)) @@ '''wroclaw'''::tsquery)"
"        ->  Bitmap Index Scan on location_lower_idx  (cost=0.00..33.95 rows=1826 width=0) (actual time=0.760..0.760 rows=1307 loops=1)"
"              Index Cond: (to_tsvector('simple'::regconfig, unaccent2((city)::text)) @@ '''wroclaw'''::tsquery)"
"Total runtime: 2.412 ms"

लेकिन जब मैं LIMIT जोड़ता हूं, तो निष्पादन में 2 सेकंड से अधिक समय लगता है:

SELECT * 
FROM location 
WHERE to_tsvector('simple',unaccent2("city"))
   @@ to_tsquery('simple',unaccent2('wroclaw')) 
order by displaycount 
limit 20

के बारे में बताएं:

"Limit  (cost=0.00..1167.59 rows=20 width=123) (actual time=2775.452..2775.643 rows=20 loops=1)"
"  ->  Index Scan using location_displaycount_index on location  (cost=0.00..106601.25 rows=1826 width=123) (actual time=2775.448..2775.637 rows=20 loops=1)"
"        Filter: (to_tsvector('simple'::regconfig, unaccent2((city)::text)) @@ '''wroclaw'''::tsquery)"
"Total runtime: 2775.693 ms"

मुझे लगता है कि यह ORDER BY और LIMIT के साथ कुछ समस्या है। मैं PostgreSQL को सूचकांक का उपयोग करने और अंत में ऑर्डर करने के लिए कैसे मजबूर कर सकता हूं?

उपश्रेणी मदद नहीं करता है:

SELECT * 
FROM (
    SELECT * 
    FROM location 
    WHERE to_tsvector('simple',unaccent2("city"))
       @@ to_tsquery('simple',unaccent2('wroclaw')) 
    order by displaycount
) t 
LIMIT 20;

या:

SELECT * 
FROM (
    SELECT * 
    FROM location 
    WHERE to_tsvector('simple',unaccent2("city"))
       @@ to_tsquery('simple',unaccent2('wroclaw'))
) t 
order by displaycount 
LIMIT 20;

जवाबों:


12

मेरा अनुमान है कि यह आपकी क्वेरी को ठीक करेगा:

SELECT * 
FROM   location 
WHERE     to_tsvector('simple',unaccent2(city))
       @@ to_tsquery('simple',unaccent2('wroclaw')) 
ORDER  BY to_tsvector('simple',unaccent2(city))
       @@ to_tsquery('simple',unaccent2('wroclaw')) DESC
         ,displaycount 
LIMIT  20;

मैं WHEREस्थिति को ORDER BYखंड के पहले तत्व के रूप में दोहराता हूं - जो तार्किक रूप से बेमानी है, लेकिन क्वेरी प्लानर को यह मानने से रोकना चाहिए कि यह अनुक्रमणिका के अनुसार प्रसंस्करण पंक्तियों से बेहतर होगा location_displaycount_index- जो अधिक महंगा निकला।

अंतर्निहित समस्या यह है कि क्वेरी प्लानर स्पष्ट रूप से आपकी WHEREस्थिति की चयनात्मकता और / या लागत को गलत तरीके से बताता है । मैं केवल अनुमान लगा सकता हूं कि ऐसा क्यों है।

क्या आपके पास ऑटोवैक्यूम चल रहा है - जिसे ANALYZEआपकी तालिकाओं पर चलने का भी ध्यान रखना चाहिए ? जिससे आपके टेबल-अप-टू-डेट हैं? कोई प्रभाव यदि आप चलाते हैं:

ANALYZE location;

और फिर प्रयत्न करें?

यह भी हो सकता है कि @@ऑपरेटर की चयनात्मकता को गलत माना जा रहा है। मैं कल्पना करूंगा कि तार्किक कारणों से अनुमान लगाना बहुत कठिन है।


यदि मेरी क्वेरी को समस्या का समाधान नहीं करना चाहिए, और आमतौर पर अंतर्निहित सिद्धांत को सत्यापित करने के लिए इन दो चीजों में से एक करें:

उत्तरार्द्ध कम घुसपैठ है और केवल वर्तमान सत्र को प्रभावित करता है। यह उन तरीकों को छोड़ देता है bitmap heap scanऔर bitmap index scanखुला रहता है, जिनका उपयोग तेज योजना द्वारा किया जाता है।
फिर क्वेरी को फिर से चलाएँ।

BTW: यदि सिद्धांत ध्वनि है, तो आपकी क्वेरी (जैसा कि आपके पास अभी है) एफटीएस की स्थिति में कम चयनात्मक खोज शब्द के साथ बहुत तेज होगी - इसके विपरीत जो आप उम्मीद कर सकते हैं। कोशिश करो।


1
क्वेरी काम करती है। इंडेक्सस्कैन को बंद करना भी काम करता है। ANALYZE काम नहीं करता है। व्यापक उत्तर के लिए आपका बहुत-बहुत धन्यवाद।
झिरी

0

जब एक लिमट पोस्टग्रैक्स्ल समायोजन का उपयोग करता है तो यह केवल उपसमुच्चय को पुनः प्राप्त करने के लिए इष्टतम होने की योजना है। दुर्भाग्य से यह किसी भी तरह से आपके मामले में गलत विकल्प बनाता है। ऐसा इसलिए हो सकता है क्योंकि तालिका के आंकड़े बहुत पुराने हैं। VACUUM ANALYZE स्थान जारी करके आंकड़े को अपडेट करने का प्रयास करें;

अनुक्रमिक स्कैन (सेट enable_seqscan = false) के उपयोग को रोककर सूचकांक का उपयोग करने के लिए मजबूर किया जाता है। हालाँकि, आपके मामले में यह अनुक्रमिक स्कैन नहीं कर रहा है, यह सिर्फ LIMIT के साथ क्वेरी के लिए एक अलग इंडेक्स पर स्विच करता है।

मामले में विश्लेषण आपको यह बताने में मदद नहीं कर सकता है कि आप किस संस्करण का उपयोग कर रहे हैं? इसके अलावा तालिका में कितनी पंक्तियाँ हैं?


विश्लेषण से मदद नहीं मिली। तालिका में लगभग 36000 पंक्तियाँ हैं और मैं postgresql 9.1 का उपयोग कर रहा हूँ।
झिरी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.