Atualização:
Veja este artigo em meu blog para uma estratégia de indexação eficiente para sua consulta usando colunas computadas:
A ideia principal é que apenas calculamos
length arredondado e startDate para seus intervalos e procure-os usando condições de igualdade (que são boas para B-Tree índices) Em
MySQL e no SQL Server 2008 você pode usar SPATIAL índices (R-Tree ). Eles são particularmente bons para condições como "selecionar todos os registros com um determinado ponto dentro do intervalo do registro", que é exatamente o seu caso.
Você armazena o
start_date e end_date como o início e o fim de uma LineString (convertendo-os para UNIX timestamps de outro valor numérico), indexe-os com um SPATIAL indexe e procure por todos esses LineString s cuja caixa delimitadora mínima (MBR ) contém o valor de data em questão, usando MBRContains . Veja esta entrada no meu blog sobre como fazer isso em
MySQL :e uma breve visão geral do desempenho do
SQL Server :A mesma solução pode ser aplicada para pesquisar um determinado
IP contra intervalos de rede armazenados no banco de dados. Essa tarefa, junto com sua consulta, é outro exemplo de tal condição frequentemente usado.
Simples
B-Tree índices não são bons se os intervalos podem se sobrepor. Se eles não puderem (e você sabe disso), você pode usar a solução brilhante proposta por
@AlexKuznetsov Observe também que o desempenho dessa consulta depende totalmente da distribuição de seus dados.
Se você tiver muitos registros em
B e poucos registros em A , você poderia apenas construir um índice em B.dates e deixe o TS/CIS em A vai. Esta consulta sempre lerá todas as linhas de
A e usará Index Seek em B.dates em um loop aninhado. Se os seus dados forem distribuídos de outra forma, i. e. você tem muitas linhas em
A mas poucos em B , e os intervalos geralmente são curtos, você pode redesenhar um pouco suas tabelas:A
start_date interval_length
, crie um índice composto em
A (interval_length, start_date) e use esta consulta:
SELECT *
FROM (
SELECT DISTINCT interval_length
FROM a
) ai
CROSS JOIN
b
JOIN a
ON a.interval_length = ai.interval_length
AND a.start_date BETWEEN b.date - ai.interval_length AND b.date