使用的方案:
屏幕前可能的疑问:
CREATE FUNCTION `st_distance`(`lat1` double,`lng1` double,`lat2` double,`lng2` double)
RETURNS double
BEGIN
DECLARE distance double;
SELECT
round(
6378.138 * 2 * asin(sqrt(pow(sin(
(lat1 * pi() / 180 - lat2 * pi() / 180) / 2
),2) + cos(lat1 * pi() / 180) * cos(lat2 * pi() / 180) * pow(
sin((lng1 * pi() / 180 - lng2 * pi() / 180) / 2),2))
) * 1000
) INTO distance;
RETURN distance;
END;
其他参考资料
1
SjwNo1 2022 年 4 月 12 日
redis geo
|
2
em70 2022 年 4 月 12 日
用 mongodb 比较适合,直接支持经纬度索引
|
3
liuzhaowei55 2022 年 4 月 12 日 via iPhone
终极解决方案 pgsql ,可以上生产的方案 mongodb ,勉强用 redis ,不太推荐用 mysql 自身的地理空间解决方案。
老手艺的话就根据已知点和距离算个正方形出来,直接和库里数据比较一下,取出来再比较距离。 需要注意的是 mongodb redis 两点间距离计算并没有根据墨卡托投影优化,两点距离越远算出来的值偏差就越大 |
4
chenliang0571 2022 年 4 月 12 日
geohash
|
5
des 2022 年 4 月 12 日 via iPhone
geohash 前缀匹配正解
|
6
CEBBCAT 2022 年 4 月 13 日
提问前 Google 的好处不止「减少社区帖子」一个好处,对自己还能锻炼自学能力,以及「兼听则明」,实在是好处多多
|
8
yggd 2022 年 4 月 13 日
geohash, S2, H3
|
9
zhangwugui 2022 年 4 月 13 日
mysql 我记得很早就支持的,5.6 还是 5.7 之后进行了优化,有专门的函数,应该主要是 st_distance 还是 st_distance_spehre 函数,以前我还写过的;
这个方法 一个是返回距离的度数,一个是返回距离的米; 大概长这样吧: SELECT s.*, (st_distance(point(lng, lat), point(122.00, 37.00) ) * 111195) AS distance FROM test s ORDER BY distance |
10
zhangwugui 2022 年 4 月 13 日
不过如果说 mysql 之外的方案,那可就多了去了,之前我们生产用 pgsql 库,pgsql 天然就适合这种操作;
|
12
tool2d 2022 年 4 月 13 日
如果静态化数据,可以自己提出来到内存,专门做地理索引。数据量大了后,应该会比 st_distance 好用一点。
|
13
dzdh 2022 年 4 月 13 日
elasticsearch > postgresql > mongodb > redis
除了 mysql 外随便挑 |
14
dzdh 2022 年 4 月 13 日
postgresql+postgis 1.2e 经纬度搜索排序 无压力
|
15
dzdh 2022 年 4 月 13 日
postgresql yyds
|
16
liuguangxuan 2022 年 5 月 13 日
@dzdh #14 老哥,在这里 E 是个什么单位?
另外我用 PostgreSQL+PostGIS 测试了一下,随机在经度(-180°~180°),纬度(-90°~90°)生成 1 亿个点,查询 32°*32°的矩形区域,搜索出来的点数大约为 150 万个,耗时需要 15 分钟。这个属于正常的吗?有没有什么优化手段可以把查询时间降下去? |
17
v2eb OP @liuguangxuan 150w 个点都要展示出来吗?
|
18
dzdh 2022 年 5 月 13 日
@liuguangxuan 同问。150w 个点都 select 出来吗
|
19
liuguangxuan 2022 年 5 月 14 日
|