Postgresql 索引两个“timestamp”列的最佳方法

Postgresql 索引两个“timestamp”列的最佳方法,postgresql,indexing,Postgresql,Indexing,我应该如何索引两个时间戳列,即start_at和ends_at,这两个列几乎总是在类似start_at>=的查询中一起使用?如果这两列是真正的时间戳,并且有少量行包含完全相同的时间戳,那么在复合键中真的没有用,因为范围扫描将无法为第一列选择单个值。如果字段是日期,这可能会有所不同,因为日期通常可以匹配时间戳不匹配的地方。这有一个小的好处,但我的经验是,这不是巨大的 如果您使用的是足够大和密集的数据,如果单个索引扫描需要扫描索引的很大一部分,则查询计划器可以使用多个索引,并将它们与位图相结合 与这

我应该如何索引两个时间戳列,即start_at和ends_at,这两个列几乎总是在类似start_at>=的查询中一起使用?如果这两列是真正的时间戳,并且有少量行包含完全相同的时间戳,那么在复合键中真的没有用,因为范围扫描将无法为第一列选择单个值。如果字段是日期,这可能会有所不同,因为日期通常可以匹配时间戳不匹配的地方。这有一个小的好处,但我的经验是,这不是巨大的

如果您使用的是足够大和密集的数据,如果单个索引扫描需要扫描索引的很大一部分,则查询计划器可以使用多个索引,并将它们与位图相结合


与这类问题一样,在数据集上运行测试是值得的。

如果这两列是真实的时间戳,并且有少量的行包含完全相同的时间戳,那么在复合键中实际上没有任何用处,因为范围扫描将无法为第一列选择单个值。如果字段是日期,这可能会有所不同,因为日期通常可以匹配时间戳不匹配的地方。这有一个小的好处,但我的经验是,这不是巨大的

如果您使用的是足够大和密集的数据,如果单个索引扫描需要扫描索引的很大一部分,则查询计划器可以使用多个索引,并将它们与位图相结合


像往常一样,这类问题值得在您的数据集上运行测试。

这是为了子孙后代的利益,因为我看到它在很久以前就得到了回答。这是以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');

。这仅仅触及了他们所能做的事情的表面。

这是为了子孙后代,因为我认为这是很久以前的回答。这是以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');

。这仅仅触及了他们能做的事情的表面。

谢谢!是的,列是没有时区的真实时间戳。而且具有完全相同值的行的数量低得离谱。我将尝试使用单索引。谢谢!是的,列是没有时区的真实时间戳。而且具有完全相同值的行的数量低得离谱。我将尝试使用单索引。