Jadual Kandungan
Related MicroZone Resources
Rumah pangkalan data tutorial mysql Using UDFs for Geo-Distance Search in MySQL_MySQL

Using UDFs for Geo-Distance Search in MySQL_MySQL

Jun 01, 2016 pm 01:07 PM

06.25.2014 | 8 views |

Proven in Production: Clustrix Case Studies

INFOGRAPHIC: The Future of the Database

Clustrix Whitepapers

What We Offer: Clustrix Features

Like this piece? Share it with your friends:

| More

Originally written by Alexander Rubin

In my previous post about geo-spatial search in MySQL I described (along with other things) how to use geo-distance functions. In this post I will describe the geo-spatial distance functions in more details.

If you need to calculate an exact distance between 2 points on Earth in MySQL (very common for geo-enabled applications) you have at least 3 choices.

  • Use stored function and implement  haversine  formula
  • Use UDF (user defined function) for haversine (see below)
  • In MySQL 5.6 you can use st_distance function (newly documented), however, you will get the distance on plane and not on earth; the value returned will be good for sorting by distance but will not represent actual miles or kilometers.

MySQL stored function for calculating distance on Earth

I previously gave an example for a MySQL-stored function which implements the haversine formula. However, the approach I used was not very precise: it was optimized for speed. If you need a more precise haversine formula implementation you can use this function (result will be in miles):

delimiter //create DEFINER = CURRENT_USER function haversine_distance_sp (lat1 double, lon1 double, lat2 double, lon2 double) returns double begin declare R int DEFAULT 3958.76; declare phi1 double; declare phi2 double; declare d_phi double; declare d_lambda double; declare a double; declare c double; declare d double; set phi1 = radians(lat1); set phi2 = radians(lat2); set d_phi = radians(lat2-lat1); set d_lambda = radians(lon2-lon1); set a = sin(d_phi/2) * sin(d_phi/2) + cos(phi1) * cos(phi2) * sin(d_lambda/2) * sin(d_lambda/2); set c = 2 * atan2(sqrt(a), sqrt(1-a)); set d = R * c; return d; end;//delimiter ;
Salin selepas log masuk

(the algorithm is based on the standard formula, I’ve used the well-known Movable Type scripts calculator )

This is a slower implementation as it uses arctangent , however it is more precise. 

MySQL UDF for Haversine distance

Another approach, which will give you much more performance is to use UDF. There are a number of implementations, I’ve used lib_mysqludf_haversine .

Here is the simple steps to install it in MySQL 5.6 (will also work with earlier versions):

$ wget 'https://github.com/lucasepe/lib_mysqludf_haversine/archive/master.zip'$ unzip master.zip$ cd lib_mysqludf_haversine-master/$ makemysql> show global variables like 'plugin%';+---------------+-------------------------+| Variable_name | Value |+---------------+-------------------------+| plugin_dir| /usr/lib64/mysql/plugin |+---------------+-------------------------+1 row in set (0.00 sec)$ sudo cp lib_mysqludf_haversine.so /usr/lib64/mysql/plugin/mysql> CREATE FUNCTION haversine_distance RETURNS REAL SONAME 'lib_mysqludf_haversine.so';mysql> select haversine_distance(37.470295464, -122.572938858498, 37.760150536, -122.20701914150199, 'mi') as dist_in_miles;+---------------+| dist_in_miles |+---------------+| 28.330467 |+---------------+1 row in set (0.00 sec)
Salin selepas log masuk

Please note:

  • Make sure you have the mysql-devel or percona-server-devel package installed (MySQL development libraries) before installing.
  • You will need to specify the last parameter to be “mi” if you want to get the results in miles, otherwise it will give you kilometers.

MySQL ST_distance function

In MySQL 5.6 you can use ST_distance function:

mysql> select st_distance(point(37.470295464, -122.572938858498), point( 37.760150536, -122.20701914150199)) as distance_plane;+---------------------+| distance_plane|+---------------------+| 0.46681174155173943 |+---------------------+1 row in set (0.00 sec)
Salin selepas log masuk

As we can see it does not give us an actual distance in mile or kilometers as it does not take into account that we have latitude and longitude, rather than X and Y on plane.

Geo Distance Functions Performance

The stored procedures and functions in MySQL are known to be slower, especially with trigonometrical functions. I’ve did a quick test, using MySQL function benchmark .

First I set 2 points (10 miles from SFO airport)

set @rlon1 = 122.572938858498;set @rlat1 = 37.470295464;set @rlon2 = -122.20701914150199;set @rlat2 = 37.760150536;
Salin selepas log masuk

Next I use 4 function to benchmark:

  • Less precise stored function (haversine)
  • More precise stored function (haversine)
  • UDF for haversine
  • MySQL 5.6 native ST_distance (plane)

The benchmark function will execute the above function 100000 times.

Here are the results:

mysql>select benchmark(100000,haversine_old_sp(@rlat1, @rlon1, @rlat2, @rlon2)) as less_precise_mysql_stored_proc;+--------------------------------+| less_precise_mysql_stored_proc |+--------------------------------+|0 |+--------------------------------+1 row in set (1.46 sec)mysql>select benchmark(100000,haversine_distance_sp(@rlat1, @rlon1, @rlat2, @rlon2)) as more_precise_mysql_stored_proc;+--------------------------------+| more_precise_mysql_stored_proc |+--------------------------------+|0 |+--------------------------------+1 row in set (2.58 sec)mysql>select benchmark(100000,haversine_distance(@rlat1, @rlon1, @rlat2, @rlon2, 'mi')) as udf_haversine_function;+------------------------+| udf_haversine_function |+------------------------+|0 |+------------------------+1 row in set (0.17 sec)mysql> select benchmark(100000, st_distance(point(@rlat1, @rlon1), point(@rlat2, @rlon1))) as mysql_builtin_st_distance;+---------------------------+| mysql_builtin_st_distance |+---------------------------+| 0 |+---------------------------+1 row in set (0.10 sec)
Salin selepas log masuk

As we can see the UDF gives much faster response time (which is comparable to built-in function).

Benchmark chart (smaller the better)

Using UDFs for Geo-Distance Search in MySQL_MySQL Conclusion

The lib_mysqludf_haversine  UDF provides a good function for geo-distance search in MySQL. Please let me know in the comments what geo-distance functions or approaches do you use in your applications.

Published at DZone with permission ofPeter Zaitsev, author and DZone MVB. ( source )

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:
  • geo-distance search
  • MySQL
  • Tips and Tricks
  • SQL
  • Tools & Methods
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimana anda mengubah jadual di MySQL menggunakan pernyataan Alter Table? Bagaimana anda mengubah jadual di MySQL menggunakan pernyataan Alter Table? Mar 19, 2025 pm 03:51 PM

Artikel ini membincangkan menggunakan pernyataan jadual Alter MySQL untuk mengubah suai jadual, termasuk menambah/menjatuhkan lajur, menamakan semula jadual/lajur, dan menukar jenis data lajur.

Bagaimana saya mengkonfigurasi penyulitan SSL/TLS untuk sambungan MySQL? Bagaimana saya mengkonfigurasi penyulitan SSL/TLS untuk sambungan MySQL? Mar 18, 2025 pm 12:01 PM

Artikel membincangkan mengkonfigurasi penyulitan SSL/TLS untuk MySQL, termasuk penjanaan sijil dan pengesahan. Isu utama menggunakan implikasi keselamatan sijil yang ditandatangani sendiri. [Kira-kira aksara: 159]

Bagaimana anda mengendalikan dataset besar di MySQL? Bagaimana anda mengendalikan dataset besar di MySQL? Mar 21, 2025 pm 12:15 PM

Artikel membincangkan strategi untuk mengendalikan dataset besar di MySQL, termasuk pembahagian, sharding, pengindeksan, dan pengoptimuman pertanyaan.

Apakah beberapa alat GUI MySQL yang popular (mis., MySQL Workbench, phpmyadmin)? Apakah beberapa alat GUI MySQL yang popular (mis., MySQL Workbench, phpmyadmin)? Mar 21, 2025 pm 06:28 PM

Artikel membincangkan alat MySQL GUI yang popular seperti MySQL Workbench dan PHPMyAdmin, membandingkan ciri dan kesesuaian mereka untuk pemula dan pengguna maju. [159 aksara]

Bagaimana anda menjatuhkan jadual di MySQL menggunakan pernyataan jadual drop? Bagaimana anda menjatuhkan jadual di MySQL menggunakan pernyataan jadual drop? Mar 19, 2025 pm 03:52 PM

Artikel ini membincangkan jadual menjatuhkan di MySQL menggunakan pernyataan Jadual Drop, menekankan langkah berjaga -jaga dan risiko. Ia menyoroti bahawa tindakan itu tidak dapat dipulihkan tanpa sandaran, memperincikan kaedah pemulihan dan bahaya persekitaran pengeluaran yang berpotensi.

Bagaimana anda mewakili hubungan menggunakan kunci asing? Bagaimana anda mewakili hubungan menggunakan kunci asing? Mar 19, 2025 pm 03:48 PM

Artikel membincangkan menggunakan kunci asing untuk mewakili hubungan dalam pangkalan data, memberi tumpuan kepada amalan terbaik, integriti data, dan perangkap umum untuk dielakkan.

Bagaimana anda membuat indeks pada lajur JSON? Bagaimana anda membuat indeks pada lajur JSON? Mar 21, 2025 pm 12:13 PM

Artikel ini membincangkan membuat indeks pada lajur JSON dalam pelbagai pangkalan data seperti PostgreSQL, MySQL, dan MongoDB untuk meningkatkan prestasi pertanyaan. Ia menerangkan sintaks dan faedah mengindeks laluan JSON tertentu, dan menyenaraikan sistem pangkalan data yang disokong.

Bagaimanakah saya menjamin MySQL terhadap kelemahan biasa (suntikan SQL, serangan kekerasan)? Bagaimanakah saya menjamin MySQL terhadap kelemahan biasa (suntikan SQL, serangan kekerasan)? Mar 18, 2025 pm 12:00 PM

Artikel membincangkan mendapatkan MySQL terhadap suntikan SQL dan serangan kekerasan menggunakan pernyataan yang disediakan, pengesahan input, dan dasar kata laluan yang kuat. (159 aksara)

See all articles