我有一个表'location_signals',有大约2.5亿条记录,ID字段有一个索引。该表具有ID,时间戳,Lat和Lon(以及其他几个未使用的列)。每个ID可能包含数千个具有不同时间戳的Lat / Lon条目。我有一个传递ID的例程,它获取该ID的所有记录,并返回一个具有最高Lat / Lon浓度的圆圈。
当我们有一万条记录时,上面的效果非常好,但是当我们导入更多数据时,它就无法再处理了。逻辑如下:
SELECT TO_TIMESTAMP(timestamp, 'MM/DD/YY HH24:MI') AS ts, *
FROM location_signals
WHERE (
extract(hour from TO_TIMESTAMP(timestamp, 'MM/DD/YY HH24:MI')) > '18'
OR extract(hour from TO_TIMESTAMP(timestamp, 'MM/DD/YY HH24:MI')) < '06'
)
AND \"DID\" = '$did'
LIMIT 1500
我认为这个问题是因为循环超过数百万的时间戳,或者其他东西。任何意见都将受到高度赞赏。也许批量做事?如果是这样,怎么样?
你应该真正修复你的timestamp
列是一个真正的时间戳。将日期/时间值存储为字符串是一个非常糟糕的主意。将列命名为将它们存储为正确的数据类型 - 好吧,在我看来,它与医疗事故有关。
因为您要搜索时间范围,所以可以在表达式上创建索引:
create index idx_location_signals_id_time on location_signals(did, to_timestamp(timestamp, 'MM/DD/YY HH24:MI')::time));
然后你可以将你的where
逻辑表达为:
where did = ? and
(to_timestamp(timestamp, 'MM/DD/YY HH24:MI')::time >= '19:00:00'::time or
to_timestamp(timestamp, 'MM/DD/YY HH24:MI')::time < '06:00:00'::time
)
这应该使用完整表达式的索引。