Uppdatering:
Se den här artikeln i min blogg för effektiv indexeringsstrategi för din fråga med hjälp av beräknade kolumner:
Huvudtanken är att vi bara beräknar avrundad length och startDate för dina intervall och sök sedan efter dem med hjälp av likhetsvillkor (som är bra för B-Tree index)
I MySQL och i SQL Server 2008 du kan använda SPATIAL index (R-Tree ).
De är särskilt bra för förhållanden som "välj alla poster med en given punkt inom postens intervall", vilket bara är ditt fall.
Du lagrar startDate och end_date som början och slutet av en LineString (konverterar dem till UNIX tidsstämplar med ett annat numeriskt värde), indexera dem med en SPATIAL indexera och sök efter alla sådana LineString s vars minsta begränsningsram (MBR ) innehåller datumvärdet i fråga, med MBRContains .
Se det här inlägget i min blogg om hur du gör detta i MySQL :
och en kort prestandaöversikt för SQL Server :
Samma lösning kan användas för att söka efter en given IP mot nätverksintervall lagrade i databasen.
Den här uppgiften, tillsammans med din fråga, är ett annat ofta använt exempel på ett sådant tillstånd.
Vanligt B-Tree index är inte bra om intervallen kan överlappa.
Om de inte kan (och du vet det), kan du använda den briljanta lösningen som föreslagits av @AlexKuznetsov
Observera också att denna frågeprestanda helt beror på din datadistribution.
Om du har många poster i B och få poster i A , du kan bara bygga ett index på B.dates och låt TS/CIS på A gå.
Denna fråga kommer alltid att läsa alla rader från A och kommer att använda Index Seek på B.dates i en kapslad slinga.
Om dina uppgifter distribueras åt andra hållet, dvs. e. du har många rader i A men få i B , och intervallen är i allmänhet korta, då kan du designa om dina tabeller lite:
A
start_date interval_length
, skapa ett sammansatt index på A (interval_length, start_date)
och använd den här frågan:
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