Directus地图字段由于B-Tree索引错误无法保存
字段Geo是一个地图类型的,使用了Postgresql数据库,保存的时候出错
{ "message": "update \"records\" set \"geo\" = st_geomfromtext($1, 4326), \"title\" = $2, \"slug\" = $3, \"author\" = $4, \"meta\" = $5, \"user_updated\" = $6, \"date_updated\" = $7 where \"id\" in ($8) - index row size 4600 exceeds btree version 4 maximum 2704 for index \"records_geo_index\"", "extensions": { "code": "INTERNAL_SERVER_ERROR" } }
原因分析
- B-Tree 索引限制:B-Tree 索引的单个索引条目不能超过 1/3 的页面大小(默认页面大小为 8KB,即单个条目限制为 ~2704 字节)。
- 几何数据大小问题:如果
geo
列的几何数据非常复杂(例如多边形或多线段,包含大量顶点),它可能会导致索引条目大小超出限制。
该错误表明表 records
中的索引 records_geo_index
出现了问题,具体是由于索引的行大小超过了 B-Tree 索引允许的最大大小(2704 字节)。这是 PostgreSQL 的限制之一。
解决方案
使用 GiST 或 SP-GiST 索引替代 B-Tree
PostGIS 提供了专门用于空间数据的索引类型(如 GiST 和 SP-GiST),它们不会受到 B-Tree 索引行大小的限制。
重新创建索引为 GiST 索引:
DROP INDEX IF EXISTS records_geo_index; CREATE INDEX records_geo_index ON records USING gist(geo);
或者,如果你的数据主要是点类型并且分布均匀,也可以使用 SP-GiST:
DROP INDEX IF EXISTS records_geo_index; CREATE INDEX records_geo_index ON records USING spgist(geo);
检查和重建表数据
如果表已经有大量复杂的空间数据,索引可能已经损坏或受到影响,可以尝试以下步骤:
DROP INDEX IF EXISTS records_geo_index;
清理表和统计信息:
VACUUM FULL records; ANALYZE records;