首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无半径MariaDB最近200个位置的距离公式

无半径MariaDB最近200个位置的距离公式
EN

Stack Overflow用户
提问于 2016-01-21 18:24:00
回答 2查看 1.3K关注 0票数 0

我有MariaDB,服务器版本: 10.0.23-MariaDB,有纬度和经度列(浮动10,6),加上一个从纬度和经度列计算的geo_location列(几何学)。

我想从一个人身上找到最近的200个人。中心的人具有传递给查询的纬度和经度。有没有办法在没有半径的情况下做到这一点?所以,如果人口密度很高,半径就会很小。如果人口密度很低,那么半径就会很大。

大约有400万行,它需要尽可能快。行可以首先根据它们所在的县进行过滤。有的县超大,人口密度低,有的县小,人口密度高。我需要最快的方法找到最近的200人。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-21 19:31:27

代码语言:javascript
复制
SELECT *, ST_DISTANCE(geo_location, POINT(lon, lat)) AS distance 
FROM geotable 
ORDER by distance DESC
LIMIT 200;

坏消息是它将非常慢,因为st_distance()没有使用任何空间索引。您应该尝试通过使用最大半径来选择较少的记录来限制查询:

代码语言:javascript
复制
set @dist = 100;
set @rlon1 = lon-@dist/abs(cos(radians(lat))*69);
set @rlon2 = lon+@dist/abs(cos(radians(lat))*69);
set @rlat1 = lat-(@dist/69);
set @rlat2 = lat+(@dist/69); 

SELECT *, ST_DISTANCE(geo_location, POINT(lon, lat)) AS distance 
FROM geotable 
WHERE ST_WITHIN(geo_location,ENVELOPE(LINESTRING(point(@rlon1, @rlat1), point(@rlon2, @rlat2)))) 
ORDER by distance DESC 
LIMIT 200;

或者,如果你有每个国家的多边形坐标,你可以用它代替最大半径。

票数 0
EN

Stack Overflow用户

发布于 2016-01-23 06:27:43

小数点6位足够好(16厘米/ 0.5英尺),但FLOAT (1.7m / 5.6英尺)降低了一些精度。将(M,N)连接到FLOATDOUBLE本质上是没有好处的;您会招致2次循环,其中一次是浪费。

由于没有“二维”索引,所以在全球范围内“查找最近的”并不是一种简单的方法。但是,通过对一个维度使用分区,对另一个维度使用集群PRIMARY KEY,您可以完成相当好的工作。

大多数解决方案的真正问题是需要在没有找到有效项的情况下命中大量磁盘块。事实上,通常超过90%的接触行是不需要的。

所有这些都在我的lat/lng博客中得到了“解决”。它将触及大约800行来获得您想要的200行,并且它们将很好地聚集在一起,所以只需要触摸几个块。它不需要对国家进行任何预先过滤,但它确实需要对谈判桌进行一些彻底的重组。而且,如果你想区分两个人互相拥抱,我建议一个缩放的INT (16毫米/ 5/8英寸)-度* 10000000。而且,FLOAT将不与PARTITIONing一起工作;INT将使用。该链接中的代码使用MEDIUMINT缩放(2.7m / 8/8英尺),但可以更改。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34931456

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档