मैं निम्न तालिका/अनुक्रमित है संयोजन Postgres -कई इंडेक्स
CREATE TABLE test
(
coords geography(Point,4326),
user_id varchar(50),
created_at timestamp
);
CREATE INDEX ix_coords ON test USING GIST (coords);
CREATE INDEX ix_user_id ON test (user_id);
CREATE INDEX ix_created_at ON test (created_at DESC);
इस क्वेरी मैं निष्पादित करने के लिए चाहते हैं:
select *
from updates
where ST_DWithin(coords, ST_MakePoint(-126.4, 45.32)::geography, 30000)
and user_id='3212312'
order by created_at desc
limit 60
जब मैं क्वेरी चलाने यह केवल ix_coords
सूचकांक का उपयोग करता है। मैं यह कैसे सुनिश्चित कर सकता हूं कि पोस्टग्रेस ix_user_id
और ix_created_at
अनुक्रमणिका के साथ-साथ क्वेरी के लिए भी उपयोग करता है?
यह एक नई तालिका है जिसमें मैंने उत्पादन डेटा की थोक प्रविष्टि की है। test
तालिका में कुल पंक्तियों: 15.069.489
मैं साथ (effective_cache_size = 2GB) PostgreSQL 9.2.1 चला रहा हूँ (PostGIS के साथ)। यह मेरा स्थानीय ओएसएक्स 16 जीबी रैम, कोर i7/2.5 गीगाहर्ट्ज, गैर-एसएसडी डिस्क है।
EXPLAIN ANALYZE
उत्पादन जोड़ना -
Limit (cost=71.64..71.65 rows=1 width=280) (actual time=1278.652..1278.665 rows=60 loops=1)
-> Sort (cost=71.64..71.65 rows=1 width=280) (actual time=1278.651..1278.662 rows=60 loops=1)
Sort Key: created_at
Sort Method: top-N heapsort Memory: 33kB
-> Index Scan using ix_coords on test (cost=0.00..71.63 rows=1 width=280) (actual time=0.198..1278.227 rows=178 loops=1)
Index Cond: (coords && '0101000020E61000006666666666E63C40C3F5285C8F824440'::geography)
Filter: (((user_id)::text = '4f1092000b921a000100015c'::text) AND ('0101000020E61000006666666666E63C40C3F5285C8F824440'::geography && _st_expand(coords, 30000::double precision)) AND _st_dwithin(coords, '0101000020E61000006666666666E63C40C3F5285C8F824440'::geography, 30000::double precision, true))
Rows Removed by Filter: 3122459
Total runtime: 1278.701 ms
अद्यतन:
नीचे दिए गए सुझावों मैं तार पर सूचकांक के आधार पर करने की कोशिश की + user_id:
CREATE INDEX ix_coords_and_user_id ON updates USING GIST (coords, user_id);
..लेकिन निम्न त्रुटि मिलती है:
ERROR: data type character varying has no default operator class for access method "gist"
HINT: You must specify an operator class for the index or define a default operator class for the data type.
अद्यतन:
तो CREATE EXTENSION btree_gist;
ने btree/gist compound अनुक्रमणिका समस्या हल की। और अब मेरी अनुक्रमणिका
CREATE INDEX ix_coords_user_id_created_at ON test USING GIST (coords, user_id, created_at);
नोट: btree_gist डीईएससी/एएससी स्वीकार नहीं करता है।
नई क्वेरी योजना:
Limit (cost=134.99..135.00 rows=1 width=280) (actual time=273.282..273.292 rows=60 loops=1)
-> Sort (cost=134.99..135.00 rows=1 width=280) (actual time=273.281..273.285 rows=60 loops=1)
Sort Key: created_at
Sort Method: quicksort Memory: 41kB
-> Index Scan using ix_updates_coords_user_id_created_at on updates (cost=0.00..134.98 rows=1 width=280) (actual time=0.406..273.110 rows=115 loops=1)
Index Cond: ((coords && '0101000020E61000006666666666E63C40C3F5285C8F824440'::geography) AND ((user_id)::text = '4e952bb5b9a77200010019ad'::text))
Filter: (('0101000020E61000006666666666E63C40C3F5285C8F824440'::geography && _st_expand(coords, 30000::double precision)) AND _st_dwithin(coords, '0101000020E61000006666666666E63C40C3F5285C8F824440'::geography, 30000::double precision, true))
Rows Removed by Filter: 1
Total runtime: 273.331 ms
क्वेरी से पहले की तुलना में बेहतर प्रदर्शन कर रहा है, लगभग एक दूसरे बेहतर है लेकिन अभी भी महान नहीं। मुझे लगता है कि यह सबसे अच्छा है जो मैं प्राप्त कर सकता हूं ?? मैं लगभग 60-80ms के आसपास उम्मीद कर रहा था। क्वेरी से order by created_at desc
भी लेते हुए, एक और 100ms बंद करता है, जिसका अर्थ है कि यह अनुक्रमणिका का उपयोग करने में असमर्थ है। इसे ठीक करने का कोई उपाय?
पोस्टग्रेर्स एक लागत आधारित योजनाकार का उपयोग करता है। यहां तक कि अगर यह इंडेक्स का उपयोग कर सकता है, तो यह उतना तेज़ नहीं हो सकता जितना इसका उपयोग नहीं कर रहा है। आप random_page_cost और cpu * cost vars के साथ यह देखने के लिए खेल सकते हैं कि आप इसे उन इंडेक्स का उपयोग करने में बात कर सकते हैं या नहीं। का विश्लेषण करने के लिए व्याख्या करें का उपयोग करें यह देखने के लिए कि यह क्या करने का निर्णय लेता है और यह कितना तेज़ है। –
एक सूचकांक का उपयोग भी उपलब्ध आंकड़ों पर निर्भर करता है। वास्तव में कितनी पंक्तियों में 'user_id = '3212312'' है? क्या आपने इस क्वेरी से पहले 'वैक्यूम विश्लेषण' किया है (कम से कम तालिका को पॉप्युलेट करने के बाद)? – wildplasser
यह देखने के लिए कि यह क्या करता है जब 'ix_coords' अनुक्रमणिका उपलब्ध नहीं है - चाहे वह अन्य अनुक्रमणिका का उपयोग कर सके और लागत क्या है - 'BEGIN; ड्रॉप इंडेक्स ix_coords ontable पर; EXPLAIN विश्लेषण_query; ROLLBACK; '। –