Hvis du kan begrænse den maksimale afstand mellem dine byer og din lokale position, så drag fordel af, at et minuts breddegrad (nord - syd) er en sømil.
Sæt et indeks på din breddegradstabel.
Lav dig selv en haversine(lat1, lat2, long1, long2, unit) gemt funktion fra haversineformlen vist i dit spørgsmål. Se nedenfor
Gør derefter dette, givet mylatitude, mylongitude og mykm.
SELECT *
from cities a
where :mylatitude >= a.latitude - :mykm/111.12
and :mylatitude <= a.latitude + :mykm/111.12
and haversine(:mylatitude,a.latitude,:mylongitude,a.longitude, 'KM') <= :mykm
order by haversine(:mylatitude,a.latitude,:mylongitude,a.longitude, 'KM')
Dette vil bruge et afgrænsningsfelt for breddegrader til groft at udelukke byer, der er for langt væk fra dit punkt. Dit DBMS vil bruge en indeksområdescanning på dit breddegradsindeks til hurtigt at udvælge de rækker i din bytabel, der er værd at overveje. Så kører den din haversinus-funktion, den med al sinus- og cosinus-matematikken, kun på disse rækker.
Jeg foreslår breddegrad, fordi længdegraden på jorden varierer med breddegraden.
Bemærk, at dette er råt. Det er fint for en butiksfinder, men brug det ikke, hvis du er civilingeniør – jorden har en elliptisk form, og det forudsætter, at den er cirkulær.
(Beklager det magiske tal på 111,12. Det er antallet af km i en breddegrad, dvs. i tres sømil.)
Se her for en brugbar afstandsfunktion.