概述
附近搜索的陷阱是把距离计算塞进 WHERE,导致全表扫描。PostGIS 的空间索引配合 ST_DWithin 可以只考察半径内的候选行,其余一概跳过。
关键步骤
- 新增 geography(Point) 列并由坐标填充。
- 在该空间列上创建 GiST 索引。
- 用 ST_DWithin 以米为半径查询。
- 用 ST_Distance 返回并排序附近结果。
验证
- EXPLAIN 显示使用空间索引。
- 结果半径以米为单位准确。
- 列表按真实距离排序。
- 数据量增长后延迟稳定。
注意事项
- PostGIS 增加扩展依赖,部分 ORM 对空间类型支持有限。
- geography 为球面距离,计算略贵;局部投影可接受时用 geometry 更省。
适用范围
本条目围绕「用 PostGIS 执行附近地点查询」给出可复制的步骤、验证方式与常见问题,适合需要按此流程落地的工程团队。执行时请结合自身上下文调整命令与阈值,并在变更前后留存证据,便于后续复核与回滚。
CREATE INDEX poi_geom_idx ON poi USING gist (geom);
SELECT name, ST_Distance(geom, $1::geography) AS meters
FROM poi
WHERE ST_DWithin(geom, $1::geography, 1000)
ORDER BY meters
LIMIT 20;