InnoDB是MySQL 5.7中唯一推荐且实际可用的GIS空间索引引擎,支持POINT、LINESTRING、POLYGON等类型上的SPATIAL索引(R-tree),而MyISAM因无事务、表锁、优化器不识别等问题已被官方标记为legacy并弃用。

MyISAM 的空间索引(SPATIAL)在 MySQL 5.7 之前更受欢迎,根本原因只有一个:InnoDB 当时不支持 SPATIAL 索引。
MySQL 5.7.5 才为 InnoDB 补全了 SPATIAL 索引支持。在此之前,如果你要对 POINT、POLYGON 这类地理数据做高效范围查询(比如“找出 5 公里内的门店”),唯一能用原生空间索引加速的引擎就是 MyISAM。
这导致不少早期 GIS 类应用、LBS 服务或地图后台直接建 MyISAM 表,并依赖 MBRContains()、MBRWithin() 这类函数走空间索引。虽然 MyISAM 没事务、易损坏,但当时没得选。
为什么 InnoDB 长期不支持 SPATIAL?
不是不想,是实现难度高:
- InnoDB 的聚簇索引结构和 MVCC 机制,跟空间索引所需的 R-Tree 实现存在天然耦合难点
- R-Tree 要求频繁分裂/合并节点并维护父子指针,而 InnoDB 的页管理、崩溃恢复逻辑最初没为这类操作优化
- MyISAM 的 R-Tree 是静态构建、只读友好的,适合它“简单粗暴”的设计哲学
现在还该用 MyISAM 做空间查询吗?
不该。除非你满足全部三个条件:
- MySQL 版本
(已极罕见) - 业务完全不要事务、不怕断电丢数据
- 查询模式极度固定,且
COUNT(*)或全表扫描性能压倒一切
哪怕你真在用老版本,也建议用 ST_ 函数 + 普通 B+ 树索引(如对经纬度建联合索引)做近似过滤,再内存后筛——比依赖 MyISAM 的脆弱空间索引更可控。
迁移 InnoDB 后空间查询变慢?先查这个
很多人把 MyISAM 表转成 InnoDB 后发现 ST_Distance() 查询变慢,不是引擎问题,而是:
-
ST_Distance()在 MySQL 5.7+ 默认用平面坐标系计算,而老 MyISAM 表可能隐式依赖球面近似 - InnoDB 的
SPATIAL索引只加速MBR类谓词(如ST_Contains()),不加速真实距离计算 - 没加
ST_SRID()显式声明坐标系,导致优化器无法选择索引
执行 EXPLAIN 看是否走了 key: spatial_key,没走就说明索引没被命中——这时候翻文档比换引擎有用得多。
真正容易被忽略的是:空间字段类型本身(GEOMETRY)在 InnoDB 中会显著增大二级索引体积,尤其当你在空间列上建了额外的普通索引。别只盯着 SPATIAL,先看实际查询路径里哪些字段真被用了。











