Мне было интересно то же самое.Я нашел два альтернативных способа сделать это, но тот, который вы предложили, был быстрее.
Я неофициально провел сравнение с одним из наших больших столов.Я ограничил запрос первыми 4 миллионами строк.Я чередовал два запроса, чтобы избежать несправедливого преимущества одного из них из-за кеширования БД.
Пройдя время эпохи / unix
SELECT to_timestamp(
(EXTRACT(epoch FROM ht.time) / EXTRACT(epoch FROM interval '5 min'))::int
* EXTRACT(epoch FROM interval '5 min')
) FROM huge_table AS ht LIMIT 4000000
(обратите внимание, что это приводит к timestamptz
даже если вы использовали тип данных, не связанный с часовым поясом)
Результаты
- Прогон 1 : 39,368 секунд
- Прогон 3 : 39,526 секунд
- Прогон 5 : 39,883 секунд
Использование date_trunc и 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
Результаты
- Прогон 2 : 34,189 секунд
- Прогон 4 : 37,028 секунд
- Запуск 6 : 32,397 секунд
Система
- Версия БД: PostgreSQL 9.6.2 включенx86_64-pc-linux-gnu, скомпилированный gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2, 64-битный
- Ядра: Intel® Xeon®, E5-1650v2, Hexa-Core
- RAM: 64 ГБ, DDR3 ECC RAM
Заключение
Ваша версия, кажется, быстреер.Но не достаточно быстро для моего конкретного случая использования.Преимущество отсутствия указания часа делает версию эпохи более универсальной и упрощает параметризацию в коде на стороне клиента.Он обрабатывает интервалы 2 hour
так же, как интервалы 5 minute
, без необходимости увеличения аргумента date_trunc
единицы времени.В заключение я хотел бы, чтобы вместо этого аргумента единицы времени был изменен аргумент временного интервала.