Eu estava pensando a mesma coisa. Encontrei duas maneiras alternativas de fazer isso, mas a que você sugeriu foi mais rápida.
Fiz uma comparação informal com uma de nossas tabelas maiores. Limitei a consulta aos primeiros 4 milhões de linhas. Eu alternei entre as duas consultas para evitar dar uma vantagem injusta devido ao cache de banco de dados.
Passando pelo tempo de época/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
(Observe que isso produz
timestamptz
mesmo se você usou um tipo de dados sem fuso horário) Resultados
- Executar 1 :39,368 segundos
- Executar 3 :39,526 segundos
- Executar 5 :39,883 segundos
Usando 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
Resultados
- Executar 2 :34,189 segundos
- Executar 4 :37,028 segundos
- Executar 6 :32,397 segundos
Sistema
- Versão do banco de dados:PostgreSQL 9.6.2 em x86_64-pc-linux-gnu, compilado por gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2, 64 bits
- Núcleos:Intel® Xeon®, E5-1650v2, Hexa-Core
- RAM:64 GB, RAM DDR3 ECC
Conclusão
Sua versão parece ser mais rápida. Mas não rápido o suficiente para o meu caso de uso específico. A vantagem de não precisar especificar a hora torna a versão epoch mais versátil e produz uma parametrização mais simples no código do lado do cliente. Ele lida com
2 hour
intervalos tão bem quanto 5 minute
intervalos sem ter que aumentar o date_trunc
argumento da unidade de tempo para cima. Em uma nota final, gostaria que este argumento de unidade de tempo fosse alterado para um argumento de intervalo de tempo.