使用Maxmind的GeoIP软件,我们可以在大约80%的时间内将IP地址的长/纬度缩小到25英里内的相对精度。
现在,我们不想使用MaxMind提供的任何其他信息,因为功能名称(即城市)之间存在很多差异,以便执行查找。如果其他方法找不到特性,我们计划尝试这样的查找,但是出于性能原因,在float上查找要比字符串快得多。
现在,我有点不知道如何找到从Maxmind到我们的数据库的最近匹配LAT/LONG。问题是,与Maxmind相比,我们的datbase特性具有更高的精度,因此直接比较可能无效。如果我们在查询期间尝试对列应用ROUND(),那显然会非常慢。
给定以下数据,最快的方法是
长79.93213
纬度39.13111
SELECT `feature_name` FROM `geo_features`
WHERE long BETWEEN 79.93 AND 79.79.94
AND lat BETWEEN 39.13 AND 39.14
有谁能想出一个优雅的解决方案,它将迅速燃烧?我知道MySQL 5中有一些新的空间存储类型,也许任何人都可以提供一个解决方案,而不是我自己设置的盲板。
最佳答案
做这件事的优雅(更准确)的方法(但不是很快)
// Closest within radius of 25 Miles
// 37, -122 are your current coordinates
// To search by kilometers instead of miles, replace 3959 with 6371
SELECT feature_name,
( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) )
* cos( radians( long ) - radians(-122) ) + sin( radians(37) )
* sin( radians( lat ) ) ) ) AS distance
FROM geo_features HAVING distance < 25
ORDER BY distance LIMIT 1;
编辑
这是从地理坐标计算圆形距离的Haversine formula。下面是这个公式在different platforms中的一些实现
R = earth’s radius (mean radius = 6,371km)
Δlat = lat2− lat1
Δlong = long2− long1
a = sin²(Δlat/2) + cos(lat1).cos(lat2).sin²(Δlong/2)
c = 2.atan2(√a, √(1−a))
d = R.c
// Note that angles need to be in radians to pass to Trigonometric functions
关于mysql - 匹配最接近的经度/纬度,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4982125/