我在 Ubuntu 12.04 上使用 PostgreSQL 9.1。
我需要在一段时间内选择记录:我的表time_limits
有两个timestamp
字段和一个integer
属性。我的实际表中有其他列与此查询无关。
create table (
start_date_time timestamp,
end_date_time timestamp,
id_phi integer,
primary key(start_date_time, end_date_time,id_phi);
该表包含大约 2M 条记录。
像下面这样的查询花费了大量的时间:
select * from time_limits as t
where t.id_phi=0
and t.start_date_time <= timestamp'2010-08-08 00:00:00'
and t.end_date_time >= timestamp'2010-08-08 00:05:00';
所以我尝试添加另一个索引 - PK的倒数:
create index idx_inversed on time_limits(id_phi, start_date_time, end_date_time);
我的印象是性能提高了:访问表中间记录的时间似乎更合理:大约在 40 到 90 秒之间。
但是对于时间范围中间的值,它仍然是几十秒。当目标是表的末尾时(按时间顺序),还有两倍。
我explain analyze
第一次尝试得到这个查询计划:
Bitmap Heap Scan on time_limits (cost=4730.38..22465.32 rows=62682 width=36) (actual time=44.446..44.446 rows=0 loops=1)
Recheck Cond: ((id_phi = 0) AND (start_date_time <= '2011-08-08 00:00:00'::timestamp without time zone) AND (end_date_time >= '2011-08-08 00:05:00'::timestamp without time zone))
-> Bitmap Index Scan on idx_time_limits_phi_start_end (cost=0.00..4714.71 rows=62682 width=0) (actual time=44.437..44.437 rows=0 loops=1)
Index Cond: ((id_phi = 0) AND (start_date_time <= '2011-08-08 00:00:00'::timestamp without time zone) AND (end_date_time >= '2011-08-08 00:05:00'::timestamp without time zone))
Total runtime: 44.507 ms
我可以做些什么来优化搜索?id_phi
您可以看到一旦设置为 ,扫描两个时间戳列所花费的所有时间0
。而且我不理解时间戳上的大扫描(60K 行!)。他们不是由主键索引并且idx_inversed
我添加的吗?
我应该从时间戳类型更改为其他类型吗?
我已经阅读了一些关于 GIST 和 GIN 索引的内容。我收集它们可以在自定义类型的某些条件下更有效。对于我的用例来说,这是一个可行的选择吗?