我应该如何索引两timestamp
列(即starts_at
和ends_at
),它们几乎总是在查询中一起使用(如starts_at >= ? AND ends_at <= ?
)?为两列创建复合索引或分别索引每一列?
顺便说一句,如果重要的话,我正在使用 Postgres :)
我应该如何索引两timestamp
列(即starts_at
和ends_at
),它们几乎总是在查询中一起使用(如starts_at >= ? AND ends_at <= ?
)?为两列创建复合索引或分别索引每一列?
顺便说一句,如果重要的话,我正在使用 Postgres :)
这是为了后代的缘故,因为我看到它很久以前就得到了回答。这假设 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');
你可以在这里阅读更多关于它们的信息。这几乎没有触及他们可以做的事情的表面。
如果这两列是真正的时间戳,其中包含完全相同的时间戳的行数很少,那么复合键确实没有用,因为范围扫描无法为第一个选择单个值。如果字段是日期,这可能会有所不同,因为日期通常可以匹配时间戳不匹配的地方。它有一点好处,但我的经验是它不是很大。
如果您使用的是足够大且密集的数据集(如果单个索引扫描需要扫描大部分索引),则查询计划器可以使用多个索引,将它们与位图结合起来。
http://www.postgresql.org/docs/current/static/indexes-bitmap-scans.html
与此类问题一样,值得在您的数据集上运行测试。