我应该如何索引两个timestamp
列(即starts_at
和ends_at
),这些列几乎总是在查询中一起使用(例如starts_at >= ? AND ends_at <= ?
)?为两列创建复合索引或分别为每一列索引?
答案 0 :(得分:3)
这是为了后人的缘故,因为我看到很久以前就回答了这个问题。这假定Postgres 9.2+。如果您有一系列日期,则应使用tsrange
作为数据类型:
create table events(
id serial primary key,
name text not null unique,
duration tsrange not null
);
关于范围的好处是你可以用它们做一些惊人的询问,根据你的需要,这是最好的部分:
create index idx_event_duration on events
using GIST(duration);
现在您可以使用各种特殊运算符进行查询:
select * from events where
duration @> (now() - interval '2 weeks');
You can read more about them here。这几乎没有说明他们能做什么。
答案 1 :(得分:1)
如果这两列是真正的时间戳,行数少,包含精确相同的时间戳,那么复合键中确实没有用,因为范围扫描无法选择第一个的单个值。如果字段是日期,则可以是不同的,因为频繁的日期可以匹配时间戳不匹配的位置。它有一个很小的好处,但我的经验是它并不是很大。
如果使用足够大且密集的数据(如果单个索引扫描需要扫描索引的大部分),查询规划器可以使用多个索引,将它们与位图组合。
http://www.postgresql.org/docs/current/static/indexes-bitmap-scans.html
与此类问题一样,值得对您的数据集运行测试。