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+兼容)。
4条答案
按热度按时间qcuzuvrc1#
我也在想同样的事情。我找到了两种替代方法来做这件事,但你建议的那个更快。
我非正式地对我们的一个较大的表进行了基准测试。我将查询限制在前400万行。我在两个查询之间交替进行,以避免由于数据库缓存而给一个不公平的优势。
经历纪元/unix时间
(Note即使您使用的是时区未知数据类型,也会生成
timestamptz
)使用日期截断和日期部分
结论
您的版本似乎更快。但对于我的特定用例来说还不够快。不必指定小时的优点使epoch版本更通用,并在客户端代码中产生更简单的参数化。它处理
2 hour
间隔和5 minute
间隔一样好,而不必增加date_trunc
时间单位参数。最后,我希望这个时间单位参数改为时间间隔参数。jchrr9hc2#
我认为没有更快的方法了。
我觉得你不必担心这个表情的表现。
执行(SELECT,UPDATE,...)语句所涉及的其他所有操作(例如,检索行的I/O)很可能比日期/时间计算的开销大得多。
shyt4zoc3#
完整查询(基于@DNS问题):
假设您有订单,并且希望按5 min和shop_id的切片对它们进行计数:
ftf50wuq4#
自Postgres 14以来,
date_bin()
是最简单和最快的:本手册:
函数
date_bin
将输入时间戳"装入"与指定原点对齐的指定间隔(步幅)。x1米2米1 x(x1米3米1 x,x1米4米1 x,x1米5米1 x)
***
source
***是timestamp
或timestamp with time zone
类型的值表达式。(date
类型的值自动转换为timestamp
。)***stride
是interval类型的值表达式。返回值同样为timestamp
或timestamp with time zone
类型。并且它标记了source
***被放置到其中的仓的开始。提供匹配数据类型的"原点",以避免由于忽略时区或假定错误时区的强制转换而产生意外结果。
我的例子 * 看起来 * 像
date
文本,但也可以作为有效的timestamp
文本。如果缺少时间部分,则假定为'00:00'。相关: