在 Postgres 中将时间戳截断为 5 分钟的最快方法是什么?

2023-12-29

Postgres 可以使用 date_trunc 函数舍入(截断)时间戳,如下所示:

date_trunc('hour', val)
date_trunc('minute', val)

我正在寻找一种将时间戳截断为最近的 5 分钟边界的方法,例如,14:26:57 变为 14:25:00。最简单的方法是这样的:

date_trunc('hour', val) + date_part('minute', val)::int / 5 * interval '5 min'

由于这是查询的性能关键部分,我想知道这是否是最快的解决方案,或者是否有一些我忽略的快捷方式(与 Postgres 8.1+ 兼容)。


我想知道同样的事情。我找到了两种替代方法,但您建议的方法更快。

我非正式地对我们的一张较大的表进行了基准测试。我将查询限制为前 400 万行。我在两个查询之间交替进行,以避免由于数据库缓存而给一个查询带来不公平的优势。


穿越 epoch/unix 时间

SELECT to_timestamp(
    floor(EXTRACT(epoch FROM ht.time) / EXTRACT(epoch FROM interval '5 min'))
    * EXTRACT(epoch FROM interval '5 min')
) FROM huge_table AS ht LIMIT 4000000

(注意这会产生timestamptz即使您使用了不知道时区的数据类型)

Results

  • Run 1:39.368秒
  • Run 3:39.526秒
  • Run 5:39.883秒

使用 date_trunc 和 date_part

SELECT 
    date_trunc('hour', ht.time) 
    + date_part('minute', ht.time)::int / 5 * interval '5 min'
FROM huge_table AS ht LIMIT 4000000

Results

  • Run 2:34.189秒
  • Run 4:37.028秒
  • Run 6:32.397秒

System

  • DB版本:x86_64-pc-linux-gnu上的PostgreSQL 9.6.2,由gcc编译(Ubuntu 4.8.2-19ubuntu1)4.8.2,64位
  • 内核:Intel® Xeon®、E5-1650v2、六核
  • 内存:64 GB,DDR3 ECC 内存

结论

你的版本似乎更快。但对于我的具体用例来说还不够快。不必指定小时的优点使得纪元版本更加通用,并在客户端代码中产生更简单的参数化。它处理2 hour间隔也一样5 minute间隔,而不必碰撞date_trunc时间单位争论起来。最后,我希望这个时间单位参数改为时间间隔参数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Postgres 中将时间戳截断为 5 分钟的最快方法是什么? 的相关文章

随机推荐