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(使用前将#替换为@)