ST_Area仅对POLYGON/MULTIPOLYGON有效,POINT/LINESTRING返回0;地理坐标系下需MySQL≥8.0.29且显式设SRID=4326才启用球面面积计算,否则结果严重失真。

ST_Area 函数只接受 POLYGON 或 MULTIPOLYGON 类型的几何值
直接对 POINT、LINESTRING 或空几何调用 ST_Area 会返回 0,不是报错——这点容易误判为“计算成功”。MySQL 不校验语义合理性,只按类型规则返回数值结果。
常见错误现象:
• 把经纬度坐标点串直接塞进 ST_GeomFromText('POINT(120 30)') 后传给 ST_Area,结果恒为 0
• 用 ST_Buffer(ST_Point(120,30), 1) 生成圆形区域后没转成多边形,仍被当 GEOMETRYCOLLECTION 处理,ST_Area 返回 NULL
- 确保输入是闭合面:用
POLYGON((x1 y1, x2 y2, ..., x1 y1))格式,首尾坐标必须严格一致 - 若数据来自 WKT 字符串,先用
ST_GeomFromText()解析,再用ST_IsValid()检查是否有效面对象 - 地理坐标(WGS84,SRID=4326)下
ST_Area默认返回球面面积(单位:平方米),但仅当显式设置 SRID 且 MySQL 版本 ≥ 8.0.29 才启用球面计算;否则按平面投影算,结果严重失真
计算地理坐标系下的真实面积必须显式指定 SRID 并验证版本支持
很多人以为只要写 ST_Area(ST_GeomFromText('POLYGON((...))', 4326)) 就自动按地球曲率算面积,实际不是。MySQL 8.0.28 及更早版本对 SRID=4326 的 ST_Area 仍走平面算法,结果可能是真实值的几倍或几分之一。
- 检查版本:
SELECT VERSION();—— 球面面积支持从 8.0.29 开始稳定生效 - 强制使用球面计算:在支持版本中,确保几何对象带 SRID 且调用前执行
SET SESSION sql_mode = 'STRICT_TRANS_TABLES';避免隐式降级 - 若无法升级,先用
ST_Transform()(需安装 SRS)转到等积投影坐标系(如 EPSG:3857 不行,得选 EPSG:6933 或自定义阿尔伯斯投影),再算面积
从表中批量计算多边形面积时注意 NULL 和无效几何的处理
生产环境中,geometry 字段常混有 NULL、空字符串、解析失败的 WKT,直接套 ST_Area(geom) 会导致整行结果变 NULL,且无提示。
- 安全写法:
ST_Area(IF(ST_IsValid(geom) AND ST_GeometryType(geom) IN ('POLYGON','MULTIPOLYGON'), geom, NULL)) - 避免隐式转换:不要把数字字段或 JSON 字符串直接丢进
ST_GeomFromText(),先用TRIM()去空格,再用REGEXP '^[PML].*\(.*\)$'粗筛格式 - 性能提醒:
ST_Area()在未建空间索引的列上执行全表扫描,大表建议对geom列加SPATIAL KEY,但注意 MySQL 的空间索引只加速范围查询,不加速函数计算本身
用 ST_Buffer 生成近似圆时,ST_Area 返回值受坐标系和缓冲距离单位影响极大
ST_Buffer(ST_Point(x,y), radius) 看似方便,但 radius 单位完全取决于当前 SRID 的线性单位。SRID=4326 下,radius=0.1 表示 0.1 度,不是 0.1 米——换算成米会随纬度变化(赤道约 11km,北纬60°只剩约 5.5km)。
- 若要生成半径 1000 米的圆:先用
ST_Buffer(ST_Transform(ST_Point(x,y), 3857), 1000),再转回 4326(可选),否则面积值无意义 -
ST_Buffer默认生成的是近似多边形(32 段圆弧),想控制精度需第三个参数:ST_Buffer(pt, 1000, 'quad_segs=64') - 注意:多次
ST_Buffer嵌套或与ST_Union混用易引发拓扑异常,ST_Area可能返回NULL,务必加ST_MakeValid()包裹
ST_Area 返回的数字看着像面积,其实只是个碰巧非零的浮点数。


















