Nie jest to odpowiedź specyficzna dla MySql, ale poprawi wydajność twojej instrukcji SQL.
To, co skutecznie robisz, to obliczanie odległości do każdego punktu w tabeli, aby sprawdzić, czy jest w odległości 10 jednostek od danego punktu.
Co możesz zrobić przed uruchomieniem tej sql, to utworzyć cztery punkty, które narysują pudełko 20 jednostek na boku, z punktem w środku, tj. (x1, y1). . . (x4, y4), gdzie (x1, y1) to (dane długie + 10 jednostek, dane Lat + 10 jednostek). . . (danyLong - 10 jednostek, danyLat -10 jednostek).
Właściwie potrzebujesz tylko dwóch punktów, nazwij je lewym górnym i prawym dolnym (X1, Y1) i (X2, Y2)
Teraz twoja instrukcja SQL używa tych punktów, aby wykluczyć wiersze, które zdecydowanie przekraczają 10u od twojego punktu, może używać indeksów szerokości i długości geograficznej, więc będzie o rząd wielkości szybszy niż to, co obecnie masz.
na przykład
select . . .
where locations.lat between X1 and X2
and locations.Long between y1 and y2;
Podejście pudełkowe może zwrócić fałszywie dodatnie (możesz zbierać punkty w rogach pudełka, które są> 10u od danego punktu), więc nadal musisz obliczyć odległość każdego punktu. Jednak to znowu będzie znacznie szybsze, ponieważ drastycznie ograniczyłeś liczbę punktów do przetestowania do punktów w ramce.
Nazywam tę technikę „Myśleniem w pudełku” :)
EDYCJA: Czy można to umieścić w jednej instrukcji SQL?
Przepraszam, nie mam pojęcia, do czego zdolny jest mój SQL lub Php. Nie wiem, gdzie najlepiej jest zbudować cztery punkty, ani jak można je przekazać do zapytania mySql w Php. Jednak gdy zdobędziesz cztery punkty, nic nie stoi na przeszkodzie, aby połączyć własną instrukcję SQL z moją.
select name,
( 3959 * acos( cos( radians(42.290763) )
* cos( radians( locations.lat ) )
* cos( radians( locations.lng ) - radians(-71.35368) )
+ sin( radians(42.290763) )
* sin( radians( locations.lat ) ) ) ) AS distance
from locations
where active = 1
and locations.lat between X1 and X2
and locations.Long between y1 and y2
having distance < 10 ORDER BY distance;
Wiem, że dzięki MS SQL mogę zbudować instrukcję SQL, która deklaruje cztery zmiennoprzecinkowe (X1, Y1, X2, Y2) i oblicza je przed „główną” instrukcją select, tak jak powiedziałem, nie mam pojęcia, czy można to zrobić za pomocą MySql. Jednak nadal będę skłonny zbudować cztery punkty w języku C # i przekazać je jako parametry do zapytania SQL.
Przykro mi, że nie mogę pomóc, jeśli ktoś może odpowiedzieć na części MySQL i Php tego, edytuj tę odpowiedź, aby to zrobić.