У меня есть такая таблица данных:
CREATE TABLE public.data
(
data_id bigint,
date timestamp without time zone,
value double precision,
sensor_id integer,
version_id integer
)
Теперь мне нужен запрос с хорошей производительностью, который извлекает все строки данных с наибольшим значением version_id для датчика и идентификатора даты.
Другими словами, это строки:
date='2018-08-24 10:31';value=1337;sensor_id=1;version_id=1;
date='2018-08-24 10:31';value=4;sensor_id=1;version_id=2;
date='2018-08-24 10:32';value=45;sensor_id=1;version_id=1;
должен привести с запросом к полученным строкам данных:
date='2018-08-24 10:31';value=4;sensor_id=1;version_id=2;
date='2018-08-24 10:32';value=45;sensor_id=1;version_id=1;
Таким образом, все строки, для которых существует более новая версия, должны игнорироваться.
Проблема в том, что мне нужна действительно хорошая производительность, потому что таблица данных может содержать, например, 2.000.000.000 строк (они разделены на задний план - думаю, это не относится к моему вопросу).
Простое решение моей проблемы - проверить для каждой строки в подзапросе, является ли она строкой с наибольшим номером версии:
SELECT * FROM data d1
WHERE d1.version_id= (
SELECT MAX(d2.version_id) FROM data d2
WHERE d2.sensor_id = d1.sensor_id AND d2.date = d2.date
);
Это очень медленно. Кстати, у меня есть следующие уникальные индексы и индексы b-дерева для этой таблицы:
CREATE UNIQUE INDEX data_unique_index
ON public.data USING btree
(sensor_id, date, version_Id);
CREATE INDEX data_version_id_idx
ON public.data USING btree
(version_id);
CREATE INDEX data_date_idx
ON public.data USING btree
(date);
CREATE INDEX data_sensor_id_idx
ON public.data USING btree
(sensor_id);
CREATE INDEX data_date_sensor_id_idx
ON public.data USING btree
(date, sensor_id);