Je me demandais la même chose. J'ai trouvé deux façons alternatives de le faire, mais celle que vous avez suggérée était plus rapide.
J'ai officieusement comparé à l'une de nos plus grandes tables. J'ai limité la requête aux 4 premiers millions de lignes. J'ai alterné entre les deux requêtes afin d'éviter de donner à l'une un avantage injuste en raison de la mise en cache de la base de données.
Traverser l'époque/l'heure 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
(Notez que cela produit timestamptz
même si vous avez utilisé un type de données ignorant le fuseau horaire)
Résultats
- Exécution 1 :39.368 secondes
- Exécuter 3 :39.526 secondes
- Exécuter 5 :39.883 secondes
Utiliser date_trunc et 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
Résultats
- Exécuter 2 :34.189 secondes
- Exécuter 4 :37.028 secondes
- Exécuter 6 :32.397 secondes
Système
- Version de la base de données :PostgreSQL 9.6.2 sur x86_64-pc-linux-gnu, compilé par gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2, 64 bits
- Cœurs :Intel® Xeon®, E5-1650v2, Hexa-Core
- RAM :64 Go, RAM DDR3 ECC
Conclusion
Votre version semble plus rapide. Mais pas assez rapide pour mon cas d'utilisation spécifique. L'avantage de ne pas avoir à spécifier l'heure rend la version d'époque plus polyvalente et produit un paramétrage plus simple dans le code côté client. Il gère 2 hour
intervalles aussi bien que 5 minute
intervalles sans avoir à bousculer le date_trunc
argument d'unité de temps vers le haut. Pour terminer, j'aimerais que cet argument d'unité de temps soit remplacé par un argument d'intervalle de temps.