Aurora MySQL空间查询返回重复结果求助(含唯一索引)
Aurora MySQL空间查询返回重复结果问题
环境信息
- 托管环境:Aurora MySQL RDS v3.04.1
- MySQL版本:v8.0.28
问题现象
对带有唯一主键uid、空间索引sp_idx的coords列(类型为point NOT NULL /*!80003 SRID 4326 */)执行ST_CONTAINS空间查询时,返回了重复的uid结果,但数据库中对应uid仅存在一行数据。
查询语句
SELECT uid FROM `table` WHERE ST_CONTAINS( ST_POLYGONFROMTEXT( 'POLYGON ((37.4434532793747721 -122.2358371757517972, 37.3985377206252210 -122.2358371757517972, 37.3985377206252210 -122.1783706242482168, 37.4434532793747721 -122.1783706242482168, 37.4434532793747721 -122.2358371757517972))', 4326 ), coords )
表结构
CREATE TABLE `table` ( `uid` bigint NOT NULL, `coords` point NOT NULL /*!80003 SRID 4326 */, PRIMARY KEY (`uid`), SPATIAL KEY `sp_idx` (`coords`), ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
已完成的排查操作
- 验证
coords列存储的坐标均为有效几何图形,无数据损坏 - 检查表及行级锁,确认无锁竞争导致的数据不一致
- 查看查询执行计划,确认已使用空间索引优化查询
- 更新数据库统计信息,确保查询优化器能生成合理执行计划
- 回滚所有未提交事务,排除事务未提交导致的数据异常
- 核对数据库实际数据,确认重复返回的
uid仅存在一行,排除数据本身重复
可能的原因及解决方案
1. 空间索引匹配逻辑bug
MySQL 8.0.28及对应Aurora版本可能存在空间查询的匹配逻辑bug,导致同一行被多次匹配。
- 临时解决方案:在查询中添加
DISTINCT去重:SELECT DISTINCT uid FROM `table` WHERE ST_CONTAINS( ST_POLYGONFROMTEXT( 'POLYGON ((37.4434532793747721 -122.2358371757517972, 37.3985377206252210 -122.2358371757517972, 37.3985377206252210 -122.1783706242482168, 37.4434532793747721 -122.1783706242482168, 37.4434532793747721 -122.2358371757517972))', 4326 ), coords ) - 彻底解决方案:升级Aurora MySQL到更高版本(如v3.05+或对应MySQL 8.0.30+版本),这类空间查询bug通常会在后续版本中修复。
2. 边界匹配异常
当点刚好落在多边形边界上时,部分版本的空间索引可能会出现重复匹配的情况。
- 解决方案:尝试调整多边形坐标的精度(如减少小数位数),或者替换为
ST_WITHIN函数测试:SELECT uid FROM `table` WHERE ST_WITHIN( coords, ST_POLYGONFROMTEXT( 'POLYGON ((37.4434532793747721 -122.2358371757517972, 37.3985377206252210 -122.2358371757517972, 37.3985377206252210 -122.1783706242482168, 37.4434532793747721 -122.1783706242482168, 37.4434532793747721 -122.2358371757517972))', 4326 ) )
3. 索引扫描逻辑异常
虽然已确认执行计划使用了空间索引,但部分场景下索引扫描可能出现重复遍历同一行的情况。
- 解决方案:强制查询不使用空间索引,改用全表扫描测试:
如果全表扫描无重复结果,说明问题出在空间索引的扫描逻辑上,此时升级数据库版本是更彻底的解决方式。SELECT uid FROM `table` IGNORE INDEX(sp_idx) WHERE ST_CONTAINS( ST_POLYGONFROMTEXT( 'POLYGON ((37.4434532793747721 -122.2358371757517972, 37.3985377206252210 -122.2358371757517972, 37.3985377206252210 -122.1783706242482168, 37.4434532793747721 -122.1783706242482168, 37.4434532793747721 -122.2358371757517972))', 4326 ), coords )
内容的提问来源于stack exchange,提问作者Subhayan
相关产品推荐
相关产品推荐

