Выбираю данные между двумя датами с количеством строк более миллиона таким запросом:
SELECT
time AT TIME ZONE 'UTC' AT TIME ZONE 'MSK' AS time,
type,
CASE
WHEN (duration > (extract(epoch from (time - '2015-08-29 12:36:50'))) )
THEN extract(epoch from (time - '2015-08-29 12:36:50'))
ELSE duration
END AS trim_duration
FROM clamps
WHERE device_id = 27 AND time BETWEEN '2015-08-29 12:36:50' AND '2016-03-15 12:36:50'
ORDER BY time ASC
Структура таблицы:
CREATE TABLE clamps
(
id serial NOT NULL,
"time" timestamp without time zone,
duration numeric,
type character varying(255),
device_id integer,
packet_id integer,
dur_float double precision DEFAULT 0,
created_at timestamp without time zone DEFAULT now(),
updated_at timestamp without time zone DEFAULT now(),
CONSTRAINT clamps_pkey PRIMARY KEY (id)
)
Имеется индекс:
CREATE UNIQUE INDEX index_clamps_on_device_id_time
ON clamps
USING btree (device_id, "time");
Explaine Analyze:
Sort (cost=149213.28..150770.01 rows=622695 width=21) (actual time=4263.385..4713.566 rows=1469514 loops=1)
Sort Key: "time"
Sort Method: external merge Disk: 71816kB
-> Bitmap Heap Scan on clamps (cost=17535.79..89284.59 rows=622695 width=21) (actual time=190.593..2692.161 rows=1469514 loops=1)
Recheck Cond: ((device_id = 27) AND ("time" >= '2015-08-29 12:36:50'::timestamp without time zone) AND ("time" <= '2016-03-15 12:36:50'::timestamp without time zone))
Heap Blocks: exact=17528
-> Bitmap Index Scan on index_clamps_on_device_id_time (cost=0.00..17380.12 rows=622695 width=0) (actual time=186.667..186.667 rows=1469514 loops=1)
Index Cond: ((device_id = 27) AND ("time" >= '2015-08-29 12:36:50'::timestamp without time zone) AND ("time" <= '2016-03-15 12:36:50'::timestamp without time zone))
Planning time: 0.291 ms
Execution time: 5414.691 ms
Запрос выполняется секунд 9-13 (хоть explain и показывает 5.5). Есть мысли как его оптимизировать?
Спасибо.