PostGIS Raster 性能评测:In-DB vs Out-DB、单通道 vs 多通道战
这是一份围绕 PostGIS Raster 栅格分析性能 的小型实测报告,重点比较了:
- In-DB 栅格 vs Out-DB 栅格
- 单通道栅格 vs 多通道栅格
- 点取值 vs 面分区统计(单个要素与 1000 个要素)
先说结论:
- Out-DB 并没有慢到“不能用”,尤其在大面分区统计场景中表现几乎与 In-DB 持平。
- 多通道 In-DB 栅格在大规模分区统计中反而略快,说明“通道多 ≠ 必然更慢”。
- 真正拉开差距的不是“存哪儿”,而是 算什么(点 vs 面)和算多少(1 个 vs 1000 个)。
测试场景与数据概况
数据与存储方式
本次测试围绕一套道路相关的栅格数据展开,使用统一的空间参考和分辨率:
- 坐标系:EPSG:3857
- 分辨率:100 × 100 m
-
数据集:
- In-DB 单通道栅格:
xxx_road_primary_indb(约 3.3 GB) - In-DB 多通道栅格:
xxx_roads_100x100(约 9.8 GB,3 个波段) - Out-DB 单通道栅格:
xxx_road_primary_outdb(约 3.3 GB,路径存储于数据库,像元数据在外部文件中)
- In-DB 单通道栅格:
In-DB:栅格像元直接存放在数据库表中
Out-DB:数据库只保存元数据和指针,实际像元存在文件系统上
矢量测试样本
-
点数据
xxx_points_random_1:随机 1 个点(单点取值)xxx_points_random_1000:随机 1000 个点(批量取值)
-
面数据
xxx_boundary:某地边界,多边形面积约 7446 km²(单个大面统计)xxx_buffer_random_1000x500:1000 个小面,每个约 0.8 km²(分区统计)
测试操作类型
核心使用 PostGIS Raster 常用函数:
- 点取值:
ST_Value(r.rast, band, point) - 面统计:
ST_SummaryStats(ST_Clip(r.rast, geom, FALSE)) - 空间过滤:
ST_Intersects(r.rast, geom, 1)
典型 SQL 形态如下(以点取值为例):
SELECT rid, ST_Value(r.rast, 1, (ST_Dump(p.geom)).geom) AS band
FROM xxx_points_random_1000 AS p, xxx_road_primary_indb AS r
WHERE ST_Intersects(r.rast, p.geom, 1);
测试用例与原始耗时
为了可复现性,每个用例都进行了 3 次运行,记录三组耗时(本文仅展示平均值,对应原始数据见下)。
| 测试用例 | In-DB 单通道 | In-DB 多通道 | Out-DB 单通道 |
|---|---|---|---|
| 单个点栅格值提取 | 398ms ; 367ms ; 401ms | 395ms ; 351ms ; 380ms | 450ms ; 452ms ; 419ms |
| 1000 个点栅格值提取 | 3m 05s ; 3m 16s ; 3m 35s | 3m 16s ; 3m 44s ; 3m 37s | 3m 47s ; 3m 40s ; 3m 47s |
| 单个面栅格统计(7446 km²) | 1m 29s ; 1m 22s ; 1m 24s | 1m 28s ; 1m 11s ; 1m 19s | 1m 18s ; 1m 18s ; 1m 23s |
| 1000 个面栅格统计(1000 × 0.8 km²) | 10m 48s ; 10m 21s ; 10m 14s | 9m 6s ; 8m 54s ; 9m 17s | 9m 14s ; 9m 11s ; 9m 14s |
下面我们用平均值来做对比分析。
结果概览:平均耗时对比
为方便比较,将三次测试结果折算为平均值(四舍五入到最近的秒)。
点栅格值提取
| 场景 | In-DB 单通道 | In-DB 多通道 | Out-DB 单通道 |
|---|---|---|---|
| 单个点 | ≈ 0.39 s | ≈ 0.38 s | ≈ 0.44 s |
| 1000 个点 | ≈ 3 min 19 s | ≈ 3 min 32 s | ≈ 3 min 45 s |
观察:
- 单点操作几乎都在 0.4 秒左右,差异可以忽略不计。
-
1000 点批量取值时:
- In-DB 单通道最快,其次是 In-DB 多通道,Out-DB 稍慢。
- Out-DB 相比 In-DB 单通道,大约慢了 ~13% 左右。
面分区栅格统计
| 场景 | In-DB 单通道 | In-DB 多通道 | Out-DB 单通道 |
|---|---|---|---|
| 单个大面(7446 km²) | ≈ 1 min 25 s | ≈ 1 min 19 s | ≈ 1 min 20 s |
| 1000 个小面(每个约 0.8 km²) | ≈ 10 min 28 s | ≈ 9 min 06 s | ≈ 9 min 13 s |
观察:
- 在“一个大面”场景中,三种存储方式都在 1 分多钟,性能几乎是一个量级,差异在 5–10 秒级别。
-
在“1000 个面”这种典型分区统计场景中:
- In-DB 多通道 反而最优,约 9 分钟出头。
- Out-DB 紧随其后,略慢于 In-DB 多通道,但仍明显快于 In-DB 单通道。
- In-DB 单通道栅格约 10 分半钟,明显慢了一档。
场景化分析
这一节我们站在“数据工程/空间分析”的视角聊聊这些数字的含义,而不只是看表格中的秒数。
点取值:Out-DB 有明显惩罚,但能接受
对于“单点”或“1000 点”这样的采样任务:
-
单点取值 0.38 vs 0.39 vs 0.44 秒,很难说谁快谁慢,更多受网络和随机抖动影响。 换句话说:交互式单点查询三种方案都够用。
-
1000 点批量取值 这里 Out-DB 的劣势就比较清晰了:
- In-DB 单通道:≈ 3′19″
- In-DB 多通道:≈ 3′32″
- Out-DB 单通道:≈ 3′45″
如果这类查询是定时批处理(例如:每天算一批点),这点差距不算什么。 但如果你希望高并发在线查询大量点(比如 API 实时响应很多客户端点采样请求),In-DB 会更稳妥一些。
粗略总结:
- 单点在线查询:任何存储方式都够快
- 大批量点采样:In-DB 更适合作为“高并发在线服务”的后端
单个大面统计:I/O 与计算均衡,三者差异不大
面对 7446 km² 这么一个大面,三种存储方式都在 1 分多,差异很小:
- In-DB 单通道:≈ 1′25″
- In-DB 多通道:≈ 1′19″
- Out-DB 单通道:≈ 1′20″
这说明:
- 这个量级的任务,已经从“谁把数据拿得快”变成了“算这块区域本身就需要一段时间”。
- Out-DB 额外的 I/O 和寻址开销被摊薄在整个计算过程里,反而不像点采样那样明显。
换句话说:单块大区域统计,选择 In-DB 还是 Out-DB,性能并不是决定性因素。
你完全可以根据:备份策略,存储空间成本,部署风格(数据库磁盘 vs 外部对象存储)来做架构选择。
1000 个面分区统计:多通道 In-DB 反而更香
这组数据很有意思,也是本次测试中最有工程价值的部分:
- In-DB 单通道:≈ 10′28″
- In-DB 多通道:≈ 9′06″
- Out-DB 单通道:≈ 9′13″
我们直觉上可能会以为: “多通道数据更大,肯定更慢。”
但结果恰恰相反:多通道 In-DB 最快。
合理的推测包括:
- 数据组织与缓存命中 多通道数据也许在写入和块划分(tile / block)时更匹配当前查询模式,在扫描时更顺滑,缓存命中率更高。
- 多次扫描 vs 一次扫描 如果后续本来就要对多个通道做统计,多通道栅格在一定程度上减少了“多表 / 多数据集来回切换”的开销。
- 数据库内部执行计划 不同表的统计信息与索引布局,可能导致优化器对多通道表给出了更高效的执行计划。
无论具体原因是什么,从使用者角度可以得出一个非常实用的结论: 当你要对同一区域做大量分区统计时,多通道 In-DB 栅格不仅不是拖累,反而可能是更经济的一种组织方式。
In-DB vs Out-DB:选型建议
基于本次测试,可以提炼出一份“偏工程实践”的选型建议。
更偏向选 In-DB 的场景
- 要做 高并发在线点采样服务(例如 API 实时给前端地图返回像元值);
- 希望把数据完全交给 数据库事务和备份 统一管理;
- 对 简单运维 比较敏感,不想额外维护外部栅格文件的路径一致性、权限、备份等问题。
可以安心使用 Out-DB 的场景
- 栅格文件本身已经有成熟的数据管理体系(如对象存储、HDFS、本地磁盘分布式管理等),数据库只是“索引和计算入口”;
-
对 批处理型任务 为主,例如:
- 定期跑分区统计
- 离线生成分析结果表
- 数据体量非常大,为了节省数据库存储成本,需要把大部分体量“放在库外”。
从本次测试数据看:
- Out-DB 在点采样上有轻微性能劣势,但在分区统计上表现很接近 In-DB。
- 如果你主要业务是 离线分析 + 大面/多面统计,走 Out-DB 完全说得过去。
多通道栅格:不必谈“通道色变”
很多项目在设计栅格结构时,都会纠结一个问题:
“我要不要拆成多个单通道栅格表?” “多通道会不会拖慢查询?”
这次实测给了一个还算让人放心的信号:
- 单点、1000 点、单个大面:多通道和单通道性能非常接近;
- 1000 面分区统计:多通道 In-DB 甚至更快。
所以更合理的思路是:
-
从“业务上真正需要的组织形式”出发设计通道结构:
- 如果几个变量总是一起被使用、一起被可视化或统计,多通道反而是自然选择;
- 如果变量之间完全独立,分成多个单通道数据集也许更清晰。
-
性能层面,不必仅仅因为“多通道可能会慢”就先天排斥多通道。
小结
结合以上测试,我们可以给出一个比较朴素但实在的结论:
-
PostGIS Raster 在数据库内部直接做栅格分析,是可行且性能可接受的。 不管是单点取值还是 1000 面分区统计,虽然时间不短,但对于离线分析和批处理来说是可以接受的量级。
-
Out-DB 不是“备用方案”,而是完全可以认真考虑的架构选择。 在大部分栅格分析场景中,它的性能和 In-DB 相当,真正决定你的体验的更多是 I/O 带宽、磁盘类型、缓存策略等底层条件。
-
多通道设计不用太担心性能拖累。 甚至在某些典型的分区统计任务中,多通道比单通道还占优。
如果要用一句话给本次测试收个尾,大概可以是: 在合理的硬件环境下,PostGIS 既能管得住你的栅格数据,也能算得动它们。至于是放在库里还是库外,更像是架构和运维风格的选择,而不是性能生死题。