Pokud můžete omezit maximální vzdálenost mezi vašimi městy a vaší místní polohou, využijte toho, že jedna minuta zeměpisné šířky (sever - jih) je jedna námořní míle.
Umístěte index do tabulky zeměpisné šířky.
Vytvořte si uloženou funkci haversine (lat1, lat2, long1, long2, unit) ze vzorce haversine uvedeného ve vaší otázce. Viz níže
Pak to udělejte s ohledem na myzeměpisnou šířku, mylongitude a 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')
To použije ohraničující pole zeměpisné šířky k hrubému vyloučení měst, která jsou příliš daleko od vašeho bodu. Váš DBMS použije skenování rozsahu indexu na vašem indexu zeměpisné šířky, aby rychle vybral řádky v tabulce vašich měst, které stojí za zvážení. Poté spustí vaši funkci haversine, tu se všemi sinusovými a kosinusovými výpočty, pouze na těchto řádcích.
Navrhuji zeměpisnou šířku, protože zemská vzdálenost zeměpisné délky se mění se zeměpisnou šířkou.
Všimněte si, že je to hrubé. Je to dobré pro vyhledávače obchodů, ale nepoužívejte to, pokud jste stavební inženýr - Země má eliptický tvar a předpokládá se, že je kruhová.
(Omlouvám se za magické číslo 111,12. To je počet km ve stupni zeměpisné šířky, to je v šedesáti námořních mílích.)
Funkční funkci vzdálenosti naleznete zde.
Proč tato uložená funkce MySQL poskytuje jiné výsledky než provádění výpočtu v dotazu?