O Postgres suporta funções de janela que se adequam a esta situação:
select date, symbol, value, created_time
from (select *,
rank() over (partition by date, symbol order by created_time desc) as rownum
from test_table) x
where rownum = 1
Para cada combinação de
date
, symbol
, esta consulta retorna o value
e created_time
da linha com o maior (ou seja, último ) created_time
dessa date
e symbol
. Sugiro este índice:
CREATE UNIQUE INDEX test_table_idx
ON test_table (date, symbol, created_time, value)
É uma cobertura index (tem todos os valores que você precisa para a consulta, eliminando a necessidade de acessar a tabela real e que você já tinha), mas observe que
created_time
vem antes value
, então os dados já estão em sua ordem de partição e value
é o atributo menos importante, pois não participa de nenhuma determinação de qual linha retornar.