Mi chiedevo la stessa cosa. Ho trovato due modi alternativi per farlo, ma quello che hai suggerito era più veloce.
Ho confrontato in modo informale uno dei nostri tavoli più grandi. Ho limitato la query alle prime 4 milioni di righe. Ho alternato le due query per evitare di dare a una un vantaggio ingiusto a causa del db caching.
Attraverso epoch/unix time
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
(Nota questo produce timestamptz
anche se hai utilizzato un tipo di dati inconsapevole del fuso orario)
Risultati
- Esegui 1 :39.368 secondi
- Esegui 3 :39.526 secondi
- Esegui 5 :39.883 secondi
Utilizzo di date_trunc e 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
Risultati
- Esegui 2 :34.189 secondi
- Esegui 4 :37.028 secondi
- Esegui 6 :32.397 secondi
Sistema
- Versione DB:PostgreSQL 9.6.2 su x86_64-pc-linux-gnu, compilato da gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2, 64-bit
- Core:Intel® Xeon®, E5-1650v2, Hexa-Core
- RAM:64 GB, RAM DDR3 ECC
Conclusione
La tua versione sembra essere più veloce. Ma non abbastanza veloce per il mio caso d'uso specifico. Il vantaggio di non dover specificare l'ora rende la versione epoch più versatile e produce una parametrizzazione più semplice nel codice lato client. Gestisce 2 hour
intervalli così come 5 minute
intervalli senza dover modificare il date_trunc
argomento dell'unità di tempo attivo. In una nota finale, vorrei che questo argomento dell'unità di tempo fosse invece cambiato in un argomento dell'intervallo di tempo.