Postgres - 从组中检索最新记录的最有效方法

时间:2021-07-16 11:47:57

标签: sql postgresql query-optimization

我们有一个表格,其中记录了所发生的作业执行情况。这个表可以变得非常大(比如 100M+ 行),尽管我们当然可以定期修剪尾部以保持它很小(比如 < 1M 行,足够的历史用于诊断)。

我们想要找到一个合理的最优查询,可以找到每种作业类型的最后一次执行。作业以不同的频率运行;有些是每秒一次,有些是每周一次。我们要跟踪的作业有几百种“类型”(一旦考虑到独特的配置。)

我们已经考虑了几个选项:

选项 1) 使用触发器更新插入到 most_recent_execution 表,在 job_configuration_id 上使用 on conflict 覆盖相同 id 的记录。好处:这将是一张只有几百行的小桌子;缺点:桌子上需要大量膨胀(和吸尘),因为会有很多更新。

选项 2) 主日志表上的 BRIN 索引,通过 execution_date/id。好处:只会在同一张桌子上工作。缺点:我们不了解多列 BRIN 索引的语义。

选项 3) 主日志表上的条件索引,它使用已知作业频率的倍数作为索引记录的日期范围限制。缺点:可能与查询规划器发生冲突。

Option 4) 主日志表上的条件索引,它使用窗口函数将每种类型的排名靠前的记录包含在索引中。缺点:再次,可能与查询规划器搏斗。

当然,我们会进行原型设计和基准测试,但如果有人做过类似的工作,我们欢迎您提出想法。

1 个答案:

答案 0 :(得分:0)

按时间范围对日志表进行分区。在最后几个分区的 (job_type, execution_time) 上有一个 b 树索引。使用 UNION 获取最后几个分区上查询的 WHERE job_type = 42 ORDER BY execution_time DESC LIMIT 1 并采用最新的。

这应该像闪电一样快,避免大索引。缺点:每个 INSERT 的索引维护成本。