Jag undrade samma sak. Jag hittade två alternativa sätt att göra detta på, men det du föreslog var snabbare.
Jag jämförde informellt med ett av våra större bord. Jag begränsade frågan till de första 4 miljoner raderna. Jag växlade mellan de två frågorna för att undvika att ge en orättvis fördel på grund av db-cache.
Gå igenom epok/unixtid
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
(Observera att detta producerar timestamptz
även om du använde en tidszon omedveten datatyp)
Resultat
- Kör 1 :39,368 sekunder
- Kör 3 :39,526 sekunder
- Kör 5 :39,883 sekunder
Använda date_trunc och 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
Resultat
- 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, kompilerad av gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2, 64-bitars
- Kärnor:Intel® Xeon®, E5-1650v2, Hexa-Core
- RAM:64 GB, DDR3 ECC RAM
Slutsats
Din version verkar vara snabbare. Men inte tillräckligt snabbt för mitt specifika användningsfall. Fördelen med att inte behöva specificera timmen gör epokversionen mer mångsidig och ger enklare parametrering i klientkod. Den hanterar 2 hour
intervaller lika bra som 5 minute
intervall utan att behöva stöta på date_trunc
tidsenhetsargument upp. Som en slutanteckning önskar jag att detta tidsenhetsargument ändrades till ett tidsintervallargument istället.