我们有一个大的位置数据库 - 每行都指定了lat long。数据库托管在MySQL中。
我们需要运行两种类型的查询:
随着记录数量的增加,此查询似乎会大幅放缓。
SELECT *, ( 3959 * acos( cos( radians(40.759105) ) * cos( radians( Latitude ) ) * cos( radians( longitude) - radians(-73.984654) ) + sin( radians(40.759105) ) * sin( radians( Latitude ) ) ) ) as distance FROM mcw_in WHERE Latitude <> '' ORDER BY distance LIMIT 0,20
如何在MySQL中创建索引以解决缓慢问题?还有其他解决方案 - 比如使用任何地理空间数据类型吗?
答案 0 :(得分:2)
答案 1 :(得分:0)
但实际上这在MySQL中不起作用,因为它们还没有真正实现这些功能。
如果你对它开放,我建议使用PostGIS或Spatialiate(分别在Postgresql和SQLLite上运行)甚至是mongodb或geocouch。它们具有更大的实现空间功能套件。如果你看一下MySQL文档,它主要说空间函数“未实现”。
答案 2 :(得分:0)
最好通过定义围绕中心的边界框来使用范围查询。以下查询搜索离中心距离$ dist的最近20个位置($ lat0,$ lng0),结果按距离排序。你需要两个索引,一个在'lat',一个在'lng'。可以找到一些解释here。
SELECT *,
( 6371 * acos(
cos(radians($lat0)) * cos(radians(lat)) * cos(radians(lng) - radians($lng0)) +
sin(radians($lat0)) * sin(radians(lat))
) ) AS distance
FROM `locations`
WHERE lat < degrees( asin( sin(radians($lat0)) * cos($dist / 6371) +
cos(radians($lat0)) * sin($dist / 6371) * cos(radians(0)) ))
AND lat > degrees( asin( sin(radians($lat0)) * cos($dist / 6371) +
cos(radians($lat0)) * sin($dist / 6371) * cos(radians(180)) ))
AND lng < $lng0 - degrees( atan2(sin(radians(90)) * sin(radians($dist / 6371)) * cos(radians($lat0)),
cos(radians($dist / 6371)) - sin(radians($lat0)) * sin(radians($lat0))) )
AND lng > $lng0 + degrees( atan2(sin(radians(90)) * sin(radians($dist / 6371)) * cos(radians($lat0)),
cos(radians($dist / 6371)) - sin(radians($lat0)) * sin(radians($lat0))) )
ORDER BY distance LIMIT 20;