索引两个“时间戳”列的最佳方法

时间:2012-12-14 12:18:54

标签: postgresql indexing

我应该如何索引两个timestamp列(即starts_atends_at),这些列几乎总是在查询中一起使用(例如starts_at >= ? AND ends_at <= ?)?为两列创建复合索引或分别为每一列索引?

是的,我正在使用Postgres,如果重要的话:)

2 个答案:

答案 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

与此类问题一样,值得对您的数据集运行测试。