मैं यह निर्धारित करने का प्रयास कर रहा हूं कि किसी WHERE
शर्त के साथ SQL क्वेरी के लिए कौन से इंडेक्स का उपयोग करना है और GROUP BY
कौन सा वर्तमान में बहुत धीमा चल रहा है।
मेरी क्वेरी:
SELECT group_id
FROM counter
WHERE ts between timestamp '2014-03-02 00:00:00.0' and timestamp '2014-03-05 12:00:00.0'
GROUP BY group_id
वर्तमान में तालिका में 32.000.000 पंक्तियाँ हैं। जब मैं समय-सीमा बढ़ाता हूं, तो क्वेरी का निष्पादन समय बहुत बढ़ जाता है।
प्रश्न की तालिका इस प्रकार है:
CREATE TABLE counter (
id bigserial PRIMARY KEY
, ts timestamp NOT NULL
, group_id bigint NOT NULL
);
मेरे पास वर्तमान में निम्नलिखित सूचकांक हैं, लेकिन प्रदर्शन अभी भी धीमा है:
CREATE INDEX ts_index
ON counter
USING btree
(ts);
CREATE INDEX group_id_index
ON counter
USING btree
(group_id);
CREATE INDEX comp_1_index
ON counter
USING btree
(ts, group_id);
CREATE INDEX comp_2_index
ON counter
USING btree
(group_id, ts);
क्वेरी पर चल रहा है निम्नलिखित परिणाम देता है:
"QUERY PLAN"
"HashAggregate (cost=467958.16..467958.17 rows=1 width=4)"
" -> Index Scan using ts_index on counter (cost=0.56..467470.93 rows=194892 width=4)"
" Index Cond: ((ts >= '2014-02-26 00:00:00'::timestamp without time zone) AND (ts <= '2014-02-27 23:59:00'::timestamp without time zone))"
उदाहरण डेटा के साथ SQL फिडेल: http://sqlfiddle.com/# -15/7492b /1
प्रश्न
क्या बेहतर अनुक्रमित जोड़कर इस क्वेरी के प्रदर्शन में सुधार किया जा सकता है, या मुझे प्रसंस्करण शक्ति बढ़ानी चाहिए?
संपादित करें 1
PostgreSQL संस्करण 9.3.2 का उपयोग किया जाता है।
संपादित करें २
मैंने @Erwin के प्रस्ताव के साथ कोशिश की EXISTS
:
SELECT group_id
FROM groups g
WHERE EXISTS (
SELECT 1
FROM counter c
WHERE c.group_id = g.group_id
AND ts BETWEEN timestamp '2014-03-02 00:00:00'
AND timestamp '2014-03-05 12:00:00'
);
लेकिन दुर्भाग्य से यह प्रदर्शन को बढ़ाने के लिए प्रतीत नहीं हुआ। क्वेरी योजना:
"QUERY PLAN"
"Nested Loop Semi Join (cost=1607.18..371680.60 rows=113 width=4)"
" -> Seq Scan on groups g (cost=0.00..2.33 rows=133 width=4)"
" -> Bitmap Heap Scan on counter c (cost=1607.18..158895.53 rows=60641 width=4)"
" Recheck Cond: ((group_id = g.id) AND (ts >= '2014-01-01 00:00:00'::timestamp without time zone) AND (ts <= '2014-03-05 12:00:00'::timestamp without time zone))"
" -> Bitmap Index Scan on comp_2_index (cost=0.00..1592.02 rows=60641 width=0)"
" Index Cond: ((group_id = g.id) AND (ts >= '2014-01-01 00:00:00'::timestamp without time zone) AND (ts <= '2014-03-05 12:00:00'::timestamp without time zone))"
संपादित करें 3
Ypercube से LATERAL क्वेरी के लिए क्वेरी योजना:
"QUERY PLAN"
"Nested Loop (cost=8.98..1200.42 rows=133 width=20)"
" -> Seq Scan on groups g (cost=0.00..2.33 rows=133 width=4)"
" -> Result (cost=8.98..8.99 rows=1 width=0)"
" One-Time Filter: ($1 IS NOT NULL)"
" InitPlan 1 (returns $1)"
" -> Limit (cost=0.56..4.49 rows=1 width=8)"
" -> Index Only Scan using comp_2_index on counter c (cost=0.56..1098691.21 rows=279808 width=8)"
" Index Cond: ((group_id = $0) AND (ts IS NOT NULL) AND (ts >= '2010-03-02 00:00:00'::timestamp without time zone) AND (ts <= '2014-03-05 12:00:00'::timestamp without time zone))"
" InitPlan 2 (returns $2)"
" -> Limit (cost=0.56..4.49 rows=1 width=8)"
" -> Index Only Scan Backward using comp_2_index on counter c_1 (cost=0.56..1098691.21 rows=279808 width=8)"
" Index Cond: ((group_id = $0) AND (ts IS NOT NULL) AND (ts >= '2010-03-02 00:00:00'::timestamp without time zone) AND (ts <= '2014-03-05 12:00:00'::timestamp without time zone))"
group_id
किसी भी गिनती में रुचि रखते हैं और नहीं?
group_id
मेज पर कितने विभिन्न मूल्य हैं?