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