Mysql
 sql >> Baza danych >  >> RDS >> Mysql

obliczenia odległości w zapytaniach mysql

Opcja 1:Wykonaj obliczenia w bazie danych, przełączając się na bazę danych, która obsługuje GeoIP.

Opcja 2:Wykonaj obliczenia w bazie danych przy użyciu procedury składowanej, takiej jak ta:

CREATE FUNCTION calcDistance (latA double, lonA double, latB double, LonB double)
    RETURNS double DETERMINISTIC
BEGIN
    SET @RlatA = radians(latA);
    SET @RlonA = radians(lonA);
    SET @RlatB = radians(latB);
    SET @RlonB = radians(LonB);
    SET @deltaLat = @RlatA - @RlatB;
    SET @deltaLon = @RlonA - @RlonB;
    SET @d = SIN(@deltaLat/2) * SIN(@deltaLat/2) +
    COS(@RlatA) * COS(@RlatB) * SIN(@deltaLon/2)*SIN(@deltaLon/2);
    RETURN 2 * ASIN(SQRT(@d)) * 6371.01;
END//

Jeśli masz w bazie danych indeks szerokości i długości geograficznej, możesz zmniejszyć liczbę obliczeń, które należy wykonać, opracowując początkową ramkę ograniczającą w PHP ($minLat, $maxLat, $minLong i $maxLong) i ograniczając wiersze do podzbioru wpisów na podstawie tego (GDZIE szerokość geograficzna BETWEEN $minLat AND $maxLat AND longitude BETWEEN $minLong AND $maxLong). Następnie MySQL musi tylko wykonać obliczenie odległości dla tego podzbioru wierszy.

Jeśli do obliczenia odległości po prostu używasz procedury składowanej), to SQL nadal musi przejrzeć każdy rekord w Twojej bazie danych i obliczyć odległość dla każdego rekordu w Twojej bazie danych, zanim będzie mógł zdecydować, czy zwrócić ten wiersz, czy go odrzucić .

Ponieważ obliczenia są stosunkowo powolne, lepiej byłoby zmniejszyć zestaw wierszy, które muszą zostać obliczone, eliminując wiersze, które wyraźnie wykraczają poza wymaganą odległość, tak że wykonujemy tylko kosztowne obliczenia dla mniejsza liczba rzędów.

Jeśli weźmiesz pod uwagę, że to, co robisz, to w zasadzie rysowanie okręgu na mapie, wyśrodkowanego na twoim początkowym punkcie i z promieniem odległości; następnie formuła po prostu identyfikuje, które wiersze znajdują się w tym okręgu... ale nadal musi sprawdzać każdy wiersz.

Używanie ramki ograniczającej jest jak rysowanie najpierw kwadratu na mapie z lewą, prawą, górną i dolną krawędzią w odpowiedniej odległości od naszego punktu środkowego. Nasz okrąg zostanie następnie narysowany w tym polu, przy czym punkty najbardziej wysunięte na północ, wschód, południe i zachód na okręgu będą dotykać granic pola. Niektóre wiersze wypadną poza to pole, więc SQL nie zadaje sobie nawet trudu, aby obliczyć odległość dla tych wierszy. Oblicza odległość tylko dla tych wierszy, które mieszczą się w obwiedni, aby sprawdzić, czy również mieszczą się w okręgu.

W twoim PHP (zgadnij, że używasz PHP z nazwy zmiennej $), możemy użyć bardzo prostego obliczenia, które oblicza minimalną i maksymalną szerokość i długość geograficzną w oparciu o naszą odległość, a następnie ustawić te wartości w klauzuli WHERE twojego SQL oświadczenie. To jest w rzeczywistości nasze pudełko, a wszystko, co wykracza poza to, jest automatycznie odrzucane bez konieczności obliczania jego odległości.

Jest to dobre wyjaśnienie (z kodem PHP) na Typ ruchomy strona internetowa to powinna być niezbędna lektura dla każdego, kto planuje wykonać jakąkolwiek pracę związaną z geopozycjonowaniem w PHP.

EDYTUJ Wartość 6371,01 w procedurze składowanej calcDistance jest mnożnikiem, który daje zwrócony wynik w kilometrach. Użyj odpowiednich alternatywnych mnożników, jeśli chcesz uzyskać mile, mile morskie, metry, cokolwiek



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Problemy z typem treści podczas ładowania urządzenia w Django

  2. Funkcja MySQL TAN() – zwraca tangens wartości w MySQL

  3. pojawia się błąd HTTP Status 405 - Metoda HTTP GET nie jest obsługiwana przez ten adres URL, ale nigdy nie była używana `get`?

  4. Najlepsze narzędzie do synchronizacji baz danych MySQL

  5. MySQL Workbench pokazuje wyniki jako BLOB