我们应该如何处理一旦它们在 PostgreSQL 中变旧就不会被查询的行?

dav*_*ley 7 postgresql performance query-performance

我们在 PostgreSQL 数据库中有一个表,它每天以数百万行的速度增长。

每行包括:

ID
Foreign user ID
Date and time
Other data
Run Code Online (Sandbox Code Playgroud)

日期和时间不是严格单调的ID,但它们很接近。

查询此表时,我们只对获取给定外部用户 ID 的行感兴趣,其中包含最近两周的日期和时间。永远不会查询超过两周的行,但我们希望保留它们以供存档。

鉴于此特殊用例:

  1. 我们应该在日期和时间列上建立索引吗?
  2. 是否有任何提示我们可以给出日期和时间(几乎)随 ID 单调增加。
  3. 我们是否应该尝试从表中删除超过两周的行,这是否可能提高性能?

Cra*_*ger 6

  1. 分区和/或使用部分索引,所以你只有你关心的部分的索引
  2. 不,AFAIK 在 Pg 中还没有相关提示。遗憾。
  3. 很大程度上取决于查询的类型,但值得这样做,特别是如果您可以通过分区来完成。

划分

这是表分区的经典用法。将表分成两部分(或更多),一部分包含热数据,另一部分包含旧存档数据。在热表上索引您需要的任何内容,并使用较少的索引来节省空间并节省insert冷表上的时间。

启用约束排除后,仅new_table当您的查询匹配分区约束时,Pg 才会自动扫描。

如果您的查询不都使用相同的约束,您可以添加一个where使用该约束的测试,或者只查询new_table分区。

部分索引

或者,您可以创建仅覆盖您感兴趣的范围的部分索引。同样,这些仅在您的查询使用约束 Pg 可以识别为匹配部分索引时才有效。在您的情况下,您必须随着时间的推移创建和删除它们以保持您的时间范围相关,因为您无法对像WHERE (some_field > current_timestamp - INTERVAL '2' week).

  • `active` 标志可用于创建部分索引,但这需要在例如 cron 作业中将“旧”行设置为 `active = false` (4认同)
  • @a_horse_with_no_name 是的;就我个人而言,我只是在“active”上进行分区并在这种情况下使用约束排除,因为无论如何您都在重写数据;同样的想法,但好点。 (2认同)