Postgres can round (truncate) timestamps using the date_trunc function, like this:
date_trunc('hour', val) date_trunc('minute', val)
I'm looking for a way to truncate a timestamp to the nearest 5-minute boundary so, for example, 14:26:57 becomes 14:25:00. The straightforward way to do it is like this:
date_trunc('hour', val) + date_part('minute', val)::int / 5 * interval '5 min'
Since this is a performance-critical part of the query, I'm wondering whether this is the fastest solution, or whether there's some shortcut (compatible with Postgres 8.1+) that I've overlooked.
I was wondering the same thing. I found two alternative ways of doing this, but the one you suggested was faster.
I informally benchmarked against one of our larger tables. I limited the query to the first 4 million rows. I alternated between the two queries in order to avoid giving one a unfair advantage due to db caching.
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
(Note this produces timestamptz
even if you used a time zone unaware datatype)
Results
SELECT date_trunc('hour', ht.time) + date_part('minute', ht.time)::int / 5 * interval '5 min' FROM huge_table AS ht LIMIT 4000000
Results
System
Your version seems to be faster. But not fast enough for my specific use case. The advantage of not having to specify the hour makes the epoch version more versatile and produces simpler parameterization in client side code. It handles 2 hour
intervals just as well as 5 minute
intervals without having to bump the date_trunc
time unit argument up. On a end note, I wish this time unit argument was changed to a time interval argument instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With