Opdatering:
Se denne artikel i min blog for effektiv indekseringsstrategi for din forespørgsel ved hjælp af beregnede kolonner:
Hovedideen er, at vi bare beregner afrundet length og startDate for dine områder, og søg derefter efter dem ved hjælp af lighedsbetingelser (som er gode for B-Tree indekser)
I MySQL og i SQL Server 2008 du kan bruge SPATIAL indekser (R-Tree ).
De er særligt gode til betingelser som "vælg alle poster med et givet punkt inden for postens rækkevidde", hvilket kun er dit tilfælde.
Du gemmer start_date og end_date som begyndelsen og slutningen af en LineString (konverterer dem til UNIX tidsstempler af en anden numerisk værdi), indekser dem med en SPATIAL indeks og søg efter alle sådanne LineString s, hvis mindste afgrænsningsramme (MBR ) indeholder den pågældende datoværdi ved hjælp af MBRContains .
Se dette indlæg i min blog om, hvordan du gør dette i MySQL :
og en kort ydeevneoversigt for SQL Server :
Samme løsning kan anvendes til at søge efter en given IP mod netværksintervaller gemt i databasen.
Denne opgave, sammen med din forespørgsel, er et andet ofte brugt eksempel på en sådan tilstand.
Almindelig B-Tree indekser er ikke gode, hvis intervallerne kan overlappe.
Hvis de ikke kan (og du ved det), kan du bruge den geniale løsning foreslået af @AlexKuznetsov
Bemærk også, at denne forespørgselsydeevne fuldstændig afhænger af din datadistribution.
Hvis du har mange poster i B og få poster i A , du kunne bare bygge et indeks på B.dates og lad TS/CIS på A gå.
Denne forespørgsel vil altid læse alle rækker fra A og vil bruge Index Seek på B.dates i en indlejret løkke.
Hvis dine data er distribueret omvendt, dvs. e. du har masser af rækker i A men få i B , og intervallerne er generelt korte, så kan du redesigne dine borde lidt:
A
start_date interval_length
, opret et sammensat indeks på A (interval_length, start_date)
og brug denne forespørgsel:
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