Эффективное получение максимальных временных меток для большой таблицы для набора идентификаторов

#postgresql #query-performance #database-partitioning

#postgresql #запрос-производительность #разделение базы данных

Вопрос:

У меня есть большая таблица базы данных PostgreSQL (на самом деле множество таблиц разделов, разделенных на кварталы за год), которая для простоты определяется примерно так

 id bigint
ts (timestamp)
value (float)
 

Для определенного набора идентификаторов какой эффективный способ найти последнюю временную метку в таблице для каждого указанного идентификатора?

Таблица индексируется по (id, timestamp)

Если я сделаю что-то наивное, например

 SELECT sensor_id, MAX(ts) 
FROM sensor_values 
WHERE ts >= (NOW()   INTERVAL '-100 days') :: TIMESTAMPTZ 
GROUP BY 1;
 

Все происходит довольно медленно.

Есть ли способ, возможно, сначала сузить время с помощью двоичного поиска по одному идентификатору (я могу предположить, что временные метки одинаковы для определенного набора идентификаторов)

Я обращаюсь к БД через psycopg, поэтому решение может быть в коде или SQL, если мне не хватает чего-то простого, чтобы ускорить это.

Объяснение запроса можно увидеть здесь. https://explain.depesz.com/s/PVqg

Любые идеи приветствуются.

Комментарии:

1. Какая у вас версия Postgres?

2. Postgres версия 12.3

3. Просто удар в темноте (и больше из любопытства), но что произойдет, если вы полностью уберете предложение where?

4. Без предложения where мне пришлось остановить запрос через 15 минут 🙂

5. У меня есть написанный метод python, который ищет значения, возвращающиеся на день назад. Как только я увижу данные, я смогу быстро получить последние значения. Раздражает, что это невозможно сделать быстро или легко в sql.