ST_Distance_Sphere返回单位是米,需除以1000转公里;仅MySQL 5.7.6+支持;参数须为POINT(longitude latitude),顺序错误或类型不匹配会导致结果失真;WHERE中使用需配合空间索引避免全表扫描。

ST_Distance_Sphere 返回单位是米,不是公里
直接调用 ST_Distance_Sphere 得到的是米(m),不是公里(km)——这是最常被忽略的单位陷阱。如果你按公里理解结果,所有距离判断都会偏差1000倍。
- 要转成公里,必须显式除以 1000:
ST_Distance_Sphere(point1, point2) / 1000 - MySQL 5.7.6+ 才支持该函数;低于此版本会报错
FUNCTION ST_Distance_Sphere does not exist - 两个参数必须都是
POINT类型,且顺序为POINT(longitude latitude)(经度在前,纬度在后),反了会导致距离严重失真
构造 POINT 时注意经纬度顺序和数据类型
MySQL 的 POINT 要求第一个坐标是经度(x),第二个是纬度(y),和常见“lat, lng”传参习惯相反。同时,ST_Distance_Sphere 对输入精度敏感,浮点数类型不一致可能引发隐式转换失败。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 正确写法:
POINT(116.404, 39.915)(北京天安门:经度 116.404,纬度 39.915) - 错误写法:
POINT(39.915, 116.404)(把 lat 当 x、lng 当 y,结果完全不可信) - 如果字段是字符串或 DECIMAL,建议显式转为
DOUBLE:POINT(CAST(lng AS DOUBLE), CAST(lat AS DOUBLE))
WHERE 条件中用 ST_Distance_Sphere 做范围筛选要加索引
直接在 WHERE 里写 ST_Distance_Sphere(...) 会导致全表扫描——即使你有 lng/lat 索引,MySQL 也无法下推优化这个函数调用。
- 先用地理围栏(bounding box)粗筛:
WHERE lng BETWEEN ? AND ? AND lat BETWEEN ? AND ?,再用ST_Distance_Sphere精筛 - 更可靠的方式是建空间索引:
ALTER TABLE locations ADD COLUMN coord POINT SRID 4326;,然后UPDATE locations SET coord = ST_PointFromText(CONCAT('POINT(', lng, ' ', lat, ')'), 4326);,最后ALTER TABLE locations ADD SPATIAL INDEX(coord); - 注意:SRID 必须是 4326(WGS84),否则
ST_Distance_Sphere可能返回 NULL 或错误值
对比 Haversine 手动计算,ST_Distance_Sphere 更准但不能替代业务校验
ST_Distance_Sphere 基于球面模型(非椭球),精度约 ±0.5%,比传统 Haversine 公式略优,但依然无法覆盖高程、道路绕行等业务实际需求。
- 它不处理地球扁率,对跨极地或超长距离(>10000 km)误差会增大
- 如果业务要求“驾车距离”,这个函数完全不适用——它只算球面直线距离
- 测试时建议用已知坐标的公开地点(如 (0,0) 和 (0,1) 应≈111.3 km)快速验证公式是否写反

















