2013-02-15 15 views
7

यहाँ Postgres 9.1.6 पर एक धीमी गति क्वेरी है, भले ही अधिकतम संख्या 2 है, दोनों पंक्तियों को पहले से ही उनके प्राथमिक कुंजी द्वारा की पहचान के साथ: (4.5 सेकंड)मैं पोस्टग्रेज़ को सबक्वायरी को रेखांकित करने से कैसे रोक सकता हूं?

EXPLAIN ANALYZE SELECT COUNT(*) FROM tbl WHERE id IN ('6d48fc431d21', 'd9e659e756ad') AND data ? 'building_floorspace' AND data ?| ARRAY['elec_mean_monthly_use', 'gas_mean_monthly_use']; 
                    QUERY PLAN                  
---------------------------------------------------------------------------------------------------------------------------------------------------- 
Aggregate (cost=4.09..4.09 rows=1 width=0) (actual time=4457.886..4457.887 rows=1 loops=1) 
    -> Index Scan using idx_tbl_on_data_gist on tbl (cost=0.00..4.09 rows=1 width=0) (actual time=4457.880..4457.880 rows=0 loops=1) 
     Index Cond: ((data ? 'building_floorspace'::text) AND (data ?| '{elec_mean_monthly_use,gas_mean_monthly_use}'::text[])) 
     Filter: ((id)::text = ANY ('{6d48fc431d21,d9e659e756ad}'::text[])) 
Total runtime: 4457.948 ms 
(5 rows) 

हम्म, शायद अगर मैं के साथ एक सबक्वेरी करना सिर्फ प्राथमिक कुंजी हिस्सा पहले ...: (नहीं, अभी भी 4.5+ सेकंड)

EXPLAIN ANALYZE SELECT COUNT(*) FROM ( SELECT * FROM tbl WHERE id IN ('6d48fc431d21', 'd9e659e756ad') ) AS t WHERE data ? 'building_floorspace' AND data ?| ARRAY['elec_mean_monthly_use', 'gas_mean_monthly_use']; 
                    QUERY PLAN                  
---------------------------------------------------------------------------------------------------------------------------------------------------- 
Aggregate (cost=4.09..4.09 rows=1 width=0) (actual time=4854.170..4854.171 rows=1 loops=1) 
    -> Index Scan using idx_tbl_on_data_gist on tbl (cost=0.00..4.09 rows=1 width=0) (actual time=4854.165..4854.165 rows=0 loops=1) 
     Index Cond: ((data ? 'building_floorspace'::text) AND (data ?| '{elec_mean_monthly_use,gas_mean_monthly_use}'::text[])) 
     Filter: ((id)::text = ANY ('{6d48fc431d21,d9e659e756ad}'::text[])) 
Total runtime: 4854.220 ms 
(5 rows) 

मैं कैसे सबक्वेरी इनलाइन करने से Postgres रोका जा सकता है?

पृष्ठभूमि: मेरे पास hstore और GiST index का उपयोग करके एक पोस्टग्रेज़ 9.1 तालिका है।

+1

जिस्ट इंडेक्स स्कैन करने पर लागत अनुमान काफी गलत लगता है (4.0 9 पर, यह प्राथमिक कुंजी की अनुक्रमणिका तक पहुंचने से कम है)। आप जांच सकते हैं कि क्या आप इसके बारे में कुछ कर सकते हैं, जैसे ताजा आंकड़े सुनिश्चित करना और/या [आंकड़े लक्ष्य] में वृद्धि करना (http://www.postgresql.org/docs/9.1/static/runtime-config-query.html#GUC -DEFAULT-सांख्यिकी-लक्ष्य)। –

+0

मैंने लक्ष्य 99 99 तक बढ़ाया और 'वैक्यूम विश्लेषण' चलाया ... अभी भी वही लागत अनुमान बनाम वास्तविकता विसंगति प्राप्त कर रहा है। हालांकि, आपके सुझाव के लिए धन्यवाद! –

उत्तर

4

जाहिर है वहाँ एक way to tell Postgres not to inline है: (0.223ms!)

EXPLAIN ANALYZE SELECT COUNT(*) FROM ( SELECT * FROM tbl WHERE id IN ('6d48fc431d21', 'd9e659e756ad') OFFSET 0) AS t WHERE data ? 'building_floorspace' AND data ?| ARRAY['elec_mean_monthly_use', 'gas_mean_monthly_use']; 
                   QUERY PLAN                 
------------------------------------------------------------------------------------------------------------------------------------------ 
Aggregate (cost=8.14..8.15 rows=1 width=0) (actual time=0.165..0.166 rows=1 loops=1) 
    -> Subquery Scan on t (cost=4.14..8.14 rows=1 width=0) (actual time=0.160..0.160 rows=0 loops=1) 
     Filter: ((t.data ? 'building_floorspace'::text) AND (t.data ?| '{elec_mean_monthly_use,gas_mean_monthly_use}'::text[])) 
     -> Limit (cost=4.14..8.13 rows=2 width=496) (actual time=0.086..0.092 rows=2 loops=1) 
       -> Bitmap Heap Scan on tbl (cost=4.14..8.13 rows=2 width=496) (actual time=0.083..0.086 rows=2 loops=1) 
        Recheck Cond: ((id)::text = ANY ('{6d48fc431d21,d9e659e756ad}'::text[])) 
        -> Bitmap Index Scan on tbl_pkey (cost=0.00..4.14 rows=2 width=0) (actual time=0.068..0.068 rows=2 loops=1) 
          Index Cond: ((id)::text = ANY ('{6d48fc431d21,d9e659e756ad}'::text[])) 
Total runtime: 0.223 ms 
(9 rows) 

चाल सबक्वेरी में OFFSET 0 है।

+0

... लेकिन PostgreSQL में क्वेरी संकेत नहीं हैं। सच में नहीं। ;-) –

7

मुझे लगता है कि OFFSET 0 बेहतर दृष्टिकोण के बाद से इसे और अधिक स्पष्ट रूप से दिखा रहा है कि कुछ अजीब हो रहा है एक हैक है है, और यह संभावना नहीं है कि हम कभी OFFSET 0 ... चारों ओर अनुकूलक व्यवहार बदल देंगे wheras उम्मीद है कि सीटीई कुछ बिंदु पर इनलाइन किए हो जाएगा है । निम्नलिखित स्पष्टीकरण पूर्णता के लिए है; सीमस के जवाब का प्रयोग करें।

असहसंबद्ध सबक्वेरी आप WITH प्रश्न शब्दों इनलाइन करने के लिए आपकी क्वेरी अलग तरीके से व्यक्त करने के लिए के रूप में PostgreSQL के इनकार दोहन कर सकते हैं के लिए:

WITH t AS (
    SELECT * FROM tbl WHERE id IN ('6d48fc431d21', 'd9e659e756ad') 
) 
SELECT COUNT(*) 
FROM t 
WHERE data ? 'building_floorspace' 
AND data ?| ARRAY['elec_mean_monthly_use', 'gas_mean_monthly_use']; 

यह OFFSET 0 हैक के रूप में ज्यादा एक ही प्रभाव है, और offset 0 की तरह पृष्ठ के दशक में कारनामे quirks हैक ऑप्टिमाइज़र जो लोगों को पीजी की क्वेरी संकेतों की कमी के बारे में जानने के लिए उपयोग करते हैं ... उन्हें क्वेरी संकेतों के रूप में उपयोग करके।

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

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