通过索引postgresql上的时间戳列加快搜索速度?

通过索引postgresql上的时间戳列加快搜索速度?,postgresql,indexing,timestamp,postgresql-performance,Postgresql,Indexing,Timestamp,Postgresql Performance,我有一个PostgreSQL数据库和一个由事件组成的表。这些事件具有列end_time,该列具有类型timestamp(无时区信息)。在我的应用程序中,我经常查询表,试图选择将来发生的所有事件。所以基本上我在做这种SQL查询: SELECT * FROM events WHERE end_time >= ?::timestamp 我目前在“结束时间”列上没有索引。我担心一旦我的表行大小变大(实际上它已经做了很多),对未来事件的搜索查询会变慢吗?因为现在数据库搜索必须遍历所有行,以选择将来

我有一个PostgreSQL数据库和一个由事件组成的表。这些事件具有列end_time,该列具有类型timestamp(无时区信息)。在我的应用程序中,我经常查询表,试图选择将来发生的所有事件。所以基本上我在做这种SQL查询:

SELECT * FROM events WHERE end_time >= ?::timestamp
我目前在“结束时间”列上没有索引。我担心一旦我的表行大小变大(实际上它已经做了很多),对未来事件的搜索查询会变慢吗?因为现在数据库搜索必须遍历所有行,以选择将来发生的行(或者更准确地说,是结束的行)。我以前使用过索引,但不能说我最熟悉它们。我想知道通过创建默认的Postgres索引来索引end_time列是否会提高查询的性能?我还没有真正的问题,但我不想等到数据量增加时再出现问题。因为那时已经太晚了,至少最终应用程序的用户体验已经降低了

我想指出的是,我使用的时间戳没有时区,因为我的应用程序总是假设本地时间,我不需要时区信息。但我听说它可能会对索引产生影响?我的时间戳目前也没有受到任何限制。因此,从理论上讲,它们可以是从现在到无限的未来。我想知道设置一些约束是否可以使索引更好?比如说活动时间应该在15年之内还是什么

另一种选择是将事件移动到过去的另一个表中(归档的事件)。这样活动的表大小就不会太大。例如,我可以有一个cron任务,定期执行

我还听说对数据库运行analyze/explain实际上可以提高它的性能?如果是这种情况,我应该多久运行一次

PostgreSQL版本:12.3

我想知道索引
end\u time
列[…]是否会提高查询的性能


如果Postgres预计未来只有少数人符合条件(拥有
结束时间
),它将在“索引扫描”或“位图索引扫描”中对列使用索引

如果这个估计不太遥远,它实际上也会提高性能。这就是为什么您应该像默认设置那样启用
autovacuum
:使列统计信息保持最新

如果实际上不需要查询中的所有列(
SELECT*
)(通常不需要),则只列出实际需要的列,以加快查询速度。甚至可能允许“仅索引扫描”。见:

我想知道设置一些约束是否可以使索引更好?比如说活动时间应该在15年之内还是什么

否。对您的查询没有任何影响。未来的行数是决定因素

我会将事件移动到另一个过去的表(已存档的事件)

Btree索引具有很好的伸缩性。这意味着,只要只有少数行符合条件,被删除行的数量就无关紧要。如果您的表很大(数百万行或数十亿行),而且大多数都是过去的,那么a可能会更好,这主要是由于索引大小和索引维护成本的减少

特别困难的是:“现在”是一个动态值。索引定义需要不可变的值。解决方法是选择一个任意的“现在”来切掉大部分行。比如:

CREATE INDEX ON events(end_time) WHERE end_time > '2021-01-30';
现代的博士后非常聪明,他们知道自己可以将索引用于未来的日期旧版本可能需要一个冗余的
WHERE
子句,以使其理解部分索引是适用的:

从事件中选择*
其中结束时间>=?::时间戳
和结束时间>'2021-01-30';--匹配索引
该指数的有效性随着时间的推移而下降,这也取决于行数的变化。您可能会不时重新创建索引以切断更多行


除此之外,不要让带有时区的类型名
timestamp
误导您。它不存储时区信息。这通常是最好的选择。见:


实际定义(
CREATE TABLE
CREATE INDEX
语句)是真理的标准来源。优于所有口头描述。请始终披露您的Postgres版本。“如果Postgres预期只有百分之几或更少的合格率(将来有结束时间),它将在“索引扫描”或“位图索引扫描”中使用列上的索引。”“只是为了清楚我正确理解这一点:它将使用索引,如果它存在,您的意思是,如果不是先手动创建,则不会自动创建?而且,我认为只有百分之几或更少的人符合条件。但不管博士后是否期待它,我不知道?这是一个很好的答案,谢谢!总之,我应该使用索引,而使用不时重新创建的部分索引会更好。@VilleMiekk oja:显然,索引只能在创建之后使用。它是自动维护的。对于这个特定的查询,部分索引更好。但是,如果您也有关于较旧日期的查询,则最好使用完整索引。用于查看实际的查询计划。