*** MYSQL 算法难题: 查询距离指定坐标 10 公里范围内的所有店铺 ***

2024-03-10 17:50:59 +08:00
 Angela2022
我有 MYSQL 表含 20 万条记录, 每条记录有店铺和位置经纬度字段. 现在我用 sql 查询距离指定坐标半径 10 公里内的所有店铺, 发现查询速度奇慢, 做了 index 后也是如此.

问题:
1. 上述需求,用啥数据格式的字段存位置经纬度合适?
2. 求最新最快的半径 10 公里内的所有店铺查询算法, 最好支持 MYSQL.

谢谢
15604 次点击
所在节点    程序员
107 条回复
xiangyuecn
2024-03-10 19:17:44 +08:00
指定中心点坐标、半径,生成圆面的代码,可以参考我的 AreaCity-Query-Geometry 代码,30 行

https://github.com/xiangyuecn/AreaCity-Query-Geometry/blob/b626c53a85350c43c64e7886e926c3e9ac877a52/AreaCityQuery.java#L1375-L1402

其中采用 Haversine formula 算法 计算经纬度坐标的距离,5 行代码
a1b2c3T
2024-03-10 19:32:43 +08:00
没记错的话 redis 好像有这个功能,
Thymolblue
2024-03-10 20:05:15 +08:00
@546L5LiK6ZOt 实际上每经度距离和纬度相关,这样算这个库在北京就用不了了。
iseki
2024-03-10 20:15:21 +08:00
以前流行过 geohash ,如果 MySQL 自己的地理信息功能挑不起来大梁,可以尝试附加一个 geohash
iseki
2024-03-10 20:17:27 +08:00
另外如果可行,还是推荐使用现成可靠的地理信息设施,比如 PostGIS ,应该比 MySQL 自己的 GIS 功能强得多
tracymcladdy
2024-03-10 21:14:38 +08:00
不要折腾,全部加载出来,一个工具类的事
sola97
2024-03-10 22:08:33 +08:00
用过 postgis
249239432
2024-03-10 22:33:25 +08:00
楼上一群半吊子,这个是计算量的问题,需要消耗 cpu 资源的,不是换个工具换个数据库就能解决

我司需求是 600 万数据查询经纬度大于 50 米,解决方案是用 spark 并行计算,20 个 task ,一个任务配置 2G 内存

后端大概 50 台刀片机服务器集群,跑一次要 16 个小时
lshero
2024-03-10 23:16:11 +08:00
非要 mysql 吗 geohash 支持那么差劲的
一般用 ES 一步到位或者 Redis 得 geohash 取出 ID 后 mget 获取详情
changdy
2024-03-10 23:16:31 +08:00
@249239432 哈哈 笑死我了才 20w 条记录... 还需要购买额外的资源... 还说别人是半吊子..
说句不客气的话..200w 数据 postgis 也是轻轻松松搞定...
楼上那么多人提到了 geo 相关的服务..你这也不反思下自己... 果然你是最独特的...

希望你的下一条回复是 "经过认真分析,确实 geo 工具有可行性"
yingqi1
2024-03-10 23:25:15 +08:00
@249239432 我也是搞大数据的,你这个 spark 的方案是真的有问题。spark 也有空间计算库 GeoSpark...。不需要硬算了。不论什么需求,一个 Job16 个小时真的吓到了。 再说了,人家 OP 是要实时查询的方法,很明显用楼上的 redis/mysql geo 数据类型可以解决。
Fa11ingWood
2024-03-10 23:25:52 +08:00
这个不知道 我司用的是 pg pg 有自带的函数 ST_within 这个函数 能实现你说的功能
249239432
2024-03-10 23:50:25 +08:00
你们就不知道好好审题?,一个心眼钻牛角尖用什么工具、框架、软件上?
集群计算速度快还是用你那台数据库或者 postgis 计算快?

@yingqi1 我用程序硬算都能算出来,纠结这东西干什么,不用集群能变快么?

@changdy 我说的是我司方案,你意淫到别人头上去了?
249239432
2024-03-10 23:54:28 +08:00
@changdy 200w 数据轻松搞定,5 个小时搞定?
lqs
2024-03-10 23:54:59 +08:00
有个很简单很取巧的做法:

经度和纬度分两个字段,并仅对纬度建立索引。由于纬度等距,相差 0.09 度大约为 10 公里,且中国大城市纬度分布差异较大,这样能利用索引初步筛选,把 20 万筛选到 5000 以内。然后再用距离公式精确计算。
dzdh
2024-03-11 00:45:48 +08:00
1.mysql 8.x 已经支持了,直接 sql 能实现,加上空间索引搜索非常快

2. redis geo 除了 mysql 之外最快的方案

3. 以上两种方案仅限于单纯的范围检索,如果是社交类的场景比如 5 公里范围内的排序外加+女的+18 的+3 天内上线过的+兴趣爱好 in (a,b,c) 的。那就老老实实上 elasticsearch 类的搜索引擎,没有任何其他方法可以最低成本实现。
yingqi1
2024-03-11 01:07:37 +08:00
@249239432 典型的数据结构问题,关集群什么事情。 审题: 20 万行数据,产品 ID (int)、经纬度(geohash) 各 8 字节。撑死 10 多 M ,要个鸡毛集群。 再说说 spark 不是框架/软件吗? 好好学习,请不要再使用“一群半吊子”的词汇了。
249239432
2024-03-11 02:02:55 +08:00
@yingqi1 这是计算量的问题,跟数据大小有什么关系,说不过就开始专牛角尖了? spark 我还不知道是什么东西么

2. 求最新最快的半径 10 公里内的所有店铺查询算法, 最好支持 MYSQL.
你这叫审题? 我用集群是不是比你用单机快?
cI137
2024-03-11 06:37:28 +08:00
有人不懂什么叫空间换时间,沙雕集群
SimbaPeng
2024-03-11 07:24:11 +08:00
果然半吊子叫的是最凶的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/1022313

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX