我有一个 PostgreSQL 数据库和一个包含事件的表。这些事件具有 end_time 列,该列具有时间戳类型(没有时区信息)。在我的应用程序中,我经常查询表,尝试选择将来发生的所有事件。所以基本上我正在做这种 SQL 查询:
SELECT * FROM events WHERE end_time >= ?::timestamp
我目前在 end_time 列上没有索引。我担心一旦我的表行大小变大(实际上它已经做了很多),对 future 事件的搜索查询会变得更慢?因为现在数据库搜索必须遍历所有行来选择将来发生的行(或更准确地说,结束)。我以前使用过索引,但不能说我是最熟悉它们的。我想知道通过创建默认的 Postgres 索引来索引 end_time 列是否会提高查询的性能?我还没有遇到真正的问题,但我不想等到数据量增加后才出现。因为那时就有点太晚了,至少最终应用程序的用户体验已经下降了。
我想指出,我确实使用不带时区的时间戳,因为我的应用程序始终假定本地时间,并且我不需要时区信息。但我听说它可能会对索引产生影响?另外,我的时间戳目前不受任何限制。所以理论上它们可以是从现在到无限的 future 。我想知道设置一些约束是否可以使索引更好?像事件时间应该在 15 年之内之类的吗?
另一种选择是我将事件移动到过去的另一个表(archived_events)。这样赛事的 table 规模就不会太大。例如,我可以有一个定期执行此操作的 cron 作业。
我还听说对数据库运行分析/解释实际上可以提高其性能?如果是这种情况,我应该多久运行一次?
PostgreSQL 版本:12.3
最佳答案
I wonder if indexing the
end_time
column [...] would increase the performance of the query?
如果 Postgres 预计只有百分之几或更少符合条件(将来有 end_time
),它将在“索引扫描”或“位图索引扫描”中使用列上的索引。
如果这个估计不是太离谱,它实际上也会提高性能。这就是为什么您应该默认启用 autovacuum
:以使列统计信息保持最新。
如果您实际上不需要查询 (SELECT *
) 中的所有列(通常不需要),则只需列出您实际需要的列,以提高速度。甚至可能允许“仅索引扫描”。请参阅:
- Postgres not using index when index scan is much better option
- Are regular VACUUM ANALYZE still recommended under 9.1?
- Postgres Slow Queries - Autovacuum frequency
I wonder if setting some constraints could make the indexing better? Something like the event time should be within 15 year or something?
不会。对您的查询没有任何影响。 future 的行数是决定因素。
I would move events to another table that are in the past (archived_events) ...?
Btree 索引具有出色的扩展性。这意味着,只要只有少数行符合条件,消除的行数就几乎不重要。如果您的表巨大(数百万或数十亿行)并且其中大部分都是过去的,则 partial index可能会更好,主要是由于索引大小和索引维护成本的减少。
特殊困难:“现在”是一个动态值。索引定义需要不可变值。解决方法是选择任意一个“现在”来切断大部分行。像这样的东西:
CREATE INDEX ON events(end_time) WHERE end_time > '2021-01-30';
现代 Postgres 足够聪明,知道它可以使用 future 日期的索引。 旧版本可能需要冗余的WHERE
子句才能使其了解部分索引适用:
SELECT * FROM events
WHERE end_time >= ?::timestamp
AND end_time > '2021-01-30'; -- match index
索引的有用性会随着时间的推移而下降,这也取决于行的变动。您可能会不时重新创建索引以切断更多行。
另外,不要让类型名称 timestamp with time zone
误导您。它不存储时区信息。它通常是最好的选择。请参阅:
关于postgresql - 通过在 postgresql 上索引时间戳列来加快搜索速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65968537/