주어진 테이블 :
Column | Type
id | integer
latitude | numeric(9,6)
longitude | numeric(9,6)
speed | integer
equipment_id | integer
created_at | timestamp without time zone
Indexes:
"geoposition_records_pkey" PRIMARY KEY, btree (id)
이 테이블에는 2 천만 건의 레코드 가 있으며 비교적 많은 수의 레코드 가 아닙니다. 그러나 순차적 스캔이 느려집니다.
max(created_at)
각각 의 마지막 레코드를 어떻게 얻을 수 equipment_id
있습니까?
이 주제에 대한 많은 답변을 읽은 몇 가지 변형을 사용하여 다음 쿼리를 모두 시도했습니다.
select max(created_at),equipment_id from geoposition_records group by equipment_id;
select distinct on (equipment_id) equipment_id,created_at
from geoposition_records order by equipment_id, created_at desc;
또한 btree 인덱스를 만들려고 equipment_id,created_at
했지만 Postgres는 seqscan을 사용하는 것이 더 빠르다는 것을 알게되었습니다. enable_seqscan = off
인덱스를 읽는 것이 seq 스캔만큼 느리기 때문에 강제 로 아무 소용이 없습니다.
쿼리는 항상 마지막을 반환하여 주기적으로 실행해야합니다.
Postgres 사용 9.3.
설명 / 분석 (170 만 레코드) :
set enable_seqscan=true;
explain analyze select max(created_at),equipment_id from geoposition_records group by equipment_id;
"HashAggregate (cost=47803.77..47804.34 rows=57 width=12) (actual time=1935.536..1935.556 rows=58 loops=1)"
" -> Seq Scan on geoposition_records (cost=0.00..39544.51 rows=1651851 width=12) (actual time=0.029..494.296 rows=1651851 loops=1)"
"Total runtime: 1935.632 ms"
set enable_seqscan=false;
explain analyze select max(created_at),equipment_id from geoposition_records group by equipment_id;
"GroupAggregate (cost=0.00..2995933.57 rows=57 width=12) (actual time=222.034..11305.073 rows=58 loops=1)"
" -> Index Scan using geoposition_records_equipment_id_created_at_idx on geoposition_records (cost=0.00..2987673.75 rows=1651851 width=12) (actual time=0.062..10248.703 rows=1651851 loops=1)"
"Total runtime: 11305.161 ms"
NULL
의 값equipment_id
예상 비율이 0.1 % 이하