Taxa de armazenamento SQL mudando no tempo e a taxa SELECT válida para um instante de tempo específico

Na tabela person_rate do SQL, armazenamos um valor flutuante de taxa que muda no tempo. Colunas:

id (serial, PK)
person_id (int)
date_from (date)
rate (float)

(person_id, date_from) é único, porque no máximo uma alteração por dia é permitida (talvez possa ser uma PK, mas não é importante)

O valor da taxa para o dado person_id é válido no domínio do tempo dedate_from data para o próximo registro com sucessodate_from, ou para o futuro infty se não houver tal registro. Exemplo:

id   person_id  date_from  rate
101  1          2011-01-01 100.0
145  1          2012-01-01 180.0
193  1          2012-05-01 140.0

Agora eu preciso de uma consulta SELECT que para cadaperson_id retorna umrate válido para alguma data dada. Deixe dizer para 2012-03-01 é 180; para 2012-05-02 é 140 e assim.

Soluções que testei:

1) condiçãodate_from <= $date + use a função de janelarank() OVER (PARTITION BY person_id ORDER BY date_from DESC + em superseleçãoWHERE rank = 1

2) semelhante a 1) mas useSELECT DISTINCT ON (person_id) em vez de limitar a classificação a 1

Ambos 1) e 2) não funcionam bem, EXPLAIN mostra que o banco de dados precisa classificar todos os registros para cadaperson_id e depois limite para 1 primeiro. Provavelmente este tipo de consulta não pode utilizar completamente o índicedate_from?

IDÉIA - adicione umdate_to column, que será um pouco redundante, porque o valor será "date_from of succesive record, menos 1 day" (ou + infty se não houver registro sucessivo). Mas a consulta poderia ser comdate_from <= $date AND date_to >= $date - que provavelmente teria um bom desempenho com índices em date_from e date_to.

Mas estou com um pouco de medo de como gerenciar a integridade dos dados nesse caso - como configurar a restrição de que [date_from .. date_to] interval para um person_id não devem ser sobrepostos?

Qual é a melhor solução para o postgresql para este tipo de consulta? A carga é mais lida, não há muita gravação na tabela person_rate. Consulta típica precisaria internamente obter uma taxa para cada dia no mês ...

Talvez istoConsulta SQL para índice / chave primária com os novos índices na página 9.2 pode ajudar de alguma forma?

questionAnswers(4)

yourAnswerToTheQuestion