进阶 postgis.net 2026-10-09 21:31:24 · 8 阅读
第30章 为什么处理大型几何图形效率低?
为什么处理大形状很慢?
因为它们就是大!在其他条件相同的情况下,对一个有 10 万个顶点的加拿大多边形做计算,自然要比对一个只有 5 个顶点的科罗拉多多边形花更多时间。
多出来的时间花在哪里?
光是把这些对象读进内存就是一笔开销。任何超过 4kb 的对象(大约 200 个顶点以上)都会被 PostgreSQL 的 TOAST 机制切成小块,存到一张旁表中。要把对象读进内存,就得取出所有分片再拼接起来。通常数据在存储时还被压缩过,所以还要多做一步解压。
为了回答一个非常局部的问题,却不得不把整个对象拉出来。你可能只想知道太平洋上的一艘渔船距离加拿大海岸线是否 100 公里,但为了回答这个问题,却要把所有大西洋省份都读进内存。
对大量顶点做计算本身也很耗时。PostGIS 会尽力对几何对象做临时索引并缓存索引信息,尽量缩小处理差距,但大的对象终究还是大。
空间范围大的对象外接矩形(bounding box)也大,这会导致索引扫描效率低下。即使顶点数不多的对象,一个糟糕的外接矩形也可能带来大量无谓计算。比如法国的外接矩形不仅覆盖法国本土,还覆盖了位于大西洋另一侧、圣劳伦斯湾的圣皮埃尔和密克隆群岛。这样一来,围绕冰岛的一次查询在索引扫描阶段可能把法国也带出来,之后还得通过更昂贵的计算把它排除掉。
能做些什么?
提升大对象性能最有效的工具是 ST_Subdivide()。它接收一个大型几何对象,输出一组多边形,每个多边形的顶点数不超过固定上限。通过切分对象,同时用主键保留对原表的引用,你可以有效地把几何对象“规范化”成更均匀的大小,从而加快空间检索。用户普遍反馈这种预处理方式效果很好。