为什么处理大型形状很慢?
因为它们很大!在条件相同的情况下,针对加拿大 100,000 个顶点的多边形进行计算所需时间肯定比针对科罗拉多州 5 个顶点的多边形进行计算所需时间更长。
导致时间增加的原因是什么?
- 将对象放入内存中以便使用。大于 4kb 的对象(即包含 200 个以上顶点的任何对象)最终会被 PostgreSQL TOAST 系统 切割成较小的部分,并存储在侧表中。将对象放入内存中涉及检索所有部分,然后将它们连接在一起。通常它们在存储时也会被压缩,因此也存在解压缩步骤。
- 为了测试一个非常局部的问题而必须提取整个对象。你可能只关心太平洋中的渔船是否距离加拿大海岸线 100 公里,但为了回答这个问题,你将把所有大西洋省份都提取到内存中。
- 对大量顶点运行计算可能需要很长时间。PostGIS 尽力对几何图形的索引信息进行临时索引和缓存,以保持处理差异,但较大的对象仍然较大。
- 空间上较大的对象具有较大的边界框,这意味着索引扫描效率低下。即使对于顶点较少的对象,错误的边界框也会导致大量计算消耗。例如,法国的边界框不仅包括法国本土,还包括圣劳伦斯湾彼岸的大西洋另一侧的圣皮埃尔和密克隆群岛。因此,围绕冰岛的查询可能会将法国作为索引扫描的一部分返回,然后必须通过更昂贵的计算排除法国。
可以采取哪些措施?
- 提高大型对象性能的最有效工具是 ST_Subdivide()。它采用单个大几何图形,并输出一组较小的几何图形,每个多边形具有固定数量的最大顶点。通过将对象切成小块,同时通过主键保留对原始表的引用,你可以有效地将几何图形“标准化”为更均匀的对象大小,以实现更快的空间搜索。用户普遍报告以这种方式对几何图形进行预处理后获得了良好的结果。