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