Jeg tænkte på det samme. Jeg fandt to alternative måder at gøre dette på, men den du foreslog var hurtigere.
Jeg benchmarkede uformelt mod et af vores større borde. Jeg begrænsede forespørgslen til de første 4 millioner rækker. Jeg skiftede mellem de to forespørgsler for at undgå at give den ene en uretfærdig fordel på grund af db-cache.
Gennem epoke/unix-tid
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
(Bemærk, at dette producerer timestamptz
selvom du brugte en tidszone uvidende datatype)
Resultater
- Kør 1 :39,368 sekunder
- Kør 3 :39,526 sekunder
- Kør 5 :39,883 sekunder
Brug af date_trunc og 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
Resultater
- Kør 2 :34,189 sekunder
- Kør 4 :37,028 sekunder
- Kør 6 :32,397 sekunder
System
- DB-version:PostgreSQL 9.6.2 på x86_64-pc-linux-gnu, kompileret af gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2, 64-bit
- Kerner:Intel® Xeon®, E5-1650v2, Hexa-Core
- RAM:64 GB, DDR3 ECC RAM
Konklusion
Din version ser ud til at være hurtigere. Men ikke hurtigt nok til min specifikke brugssag. Fordelen ved ikke at skulle angive timen gør epokeversionen mere alsidig og giver en enklere parameterisering i klientsidekoden. Den håndterer 2 hour
intervaller lige så godt som 5 minute
intervaller uden at skulle bumpe date_trunc
tidsenhedsargumentet op. Til sidst ville jeg ønske, at dette tidsenhedsargument blev ændret til et tidsintervalargument i stedet for.