如何改善空间连接?
How to improve spatial join?
我是 运行 这个空间连接,针对 400 行大约 2500 万行的两个多边形图层。我已经检查了无效的几何图形,但没有人出现..
我已将存储设置为外部存储并在 geom 字段中创建索引作为要点。
- table1_field1_idx(btree,非聚类,field1)
- table1_geom_idx (gist, not clustered, geom)
- table2_geom_idx(要点,非集群,geom)
- table2_ogc_fid_idx(btree,未聚类,ogc_fid)
查询计划
嵌套循环内连接
2. 对table2进行seq扫描作为att
3. 作为 g 在 ltable1 上进行位图堆扫描
重新检查条件:(g.geom && att.geom)
4. 使用 table1_geom_idx 进行位图索引扫描
索引条件:(g.geom && att.geom)
但是性能真的很差,服务器断开前的最后一次尝试花了20多个小时才失败,因为服务器断开。
我正在使用 postgresql 11 postgis,我在 aws 实例中尝试了本地和远程桌面,两者的性能相似。
SELECT g.field1,
att.ogc_fid,
st_intersection(g.geom, att.geom) AS intersect_geom,
st_area(g.geom) AS geom_area,
st_area(st_intersection(g.geom, att.geom)) AS intersect_area
FROM table1 g
JOIN table2 att ON g.geom && att.geom;
四处走动后,我也尝试了子查询,但不确定是否可行:
WITH g AS (
SELECT field1,
count(*) AS num_polygons,
table1.geom
FROM table1
GROUP BY table1.field1, table1.geom
)
SELECT g.field1,
att.field2,
st_intersection(g.geom, att.geom) AS intersect_geom,
st_area(g.geom) AS geom_area,
st_area(st_intersection(g.geom, att.geom)) AS intersect_area
FROM g
JOIN table2 att ON g.geom && att.geom
WHERE ST_IsValid(att.geom) AND ST_IsValid(g.geom);
我想提高性能,如有任何帮助,我们将不胜感激。
此答案假定几何列已正确编入索引,例如使用 gist
:
CREATE INDEX idx_tb1_geom ON table1 USING gist (geom);
CREATE INDEX idx_tb2_geom ON table2 USING gist (geom);
您的查询在空间上连接了包含 400 和 2500 万条记录的两个表 没有 WHERE
子句,这意味着它可能 return 两个表的笛卡尔积。这是一个巨大的结果集!
我使用包含 403 条记录和 table2
500 万条记录的 table1
复制了您的环境,并且它的工作速度非常快。为了说明我的观点,如果我们简单地计算重叠的几何数量(而不实际检索它们),查询运行得非常快:
EXPLAIN (ANALYSE,COSTS OFF)
SELECT count(att.*)
FROM table1 g
JOIN table2 att ON g.geom && att.geom;
QUERY PLAN
---------------------------------------------------------------------------------------------------
Aggregate (actual time=516.299..516.300 rows=1 loops=1)
-> Nested Loop (actual time=6.118..501.909 rows=281212 loops=1)
-> Seq Scan on table1 g (actual time=0.060..0.312 rows=403 loops=1)
-> Bitmap Heap Scan on table2 att (actual time=0.187..1.198 rows=698 loops=403)
Recheck Cond: (g.geom && geom)
Heap Blocks: exact=279398
-> Bitmap Index Scan on idx_tb2_geom (actual time=0.108..0.108 rows=698 loops=403)
Index Cond: (geom && g.geom)
Planning Time: 0.505 ms
Execution Time: 519.337 ms
请注意,查询在 519ms 中过滤了 281212 个几何图形,这对于数据量而言并不是最差的性能。但是,如果您决定检索这 281212 个几何图形,情况就会大不相同,因为您会遇到其他瓶颈,例如可用内存和网络速度。
一条经验法则:永远不要将数据带到软件中,而是将软件带到数据中!这意味着在将数据加载到应用程序之前,您应该尽可能多地在数据库中处理数据。
我是 运行 这个空间连接,针对 400 行大约 2500 万行的两个多边形图层。我已经检查了无效的几何图形,但没有人出现..
我已将存储设置为外部存储并在 geom 字段中创建索引作为要点。
- table1_field1_idx(btree,非聚类,field1)
- table1_geom_idx (gist, not clustered, geom)
- table2_geom_idx(要点,非集群,geom)
- table2_ogc_fid_idx(btree,未聚类,ogc_fid)
查询计划
嵌套循环内连接 2. 对table2进行seq扫描作为att 3. 作为 g 在 ltable1 上进行位图堆扫描 重新检查条件:(g.geom && att.geom) 4. 使用 table1_geom_idx 进行位图索引扫描 索引条件:(g.geom && att.geom)
但是性能真的很差,服务器断开前的最后一次尝试花了20多个小时才失败,因为服务器断开。
我正在使用 postgresql 11 postgis,我在 aws 实例中尝试了本地和远程桌面,两者的性能相似。
SELECT g.field1,
att.ogc_fid,
st_intersection(g.geom, att.geom) AS intersect_geom,
st_area(g.geom) AS geom_area,
st_area(st_intersection(g.geom, att.geom)) AS intersect_area
FROM table1 g
JOIN table2 att ON g.geom && att.geom;
四处走动后,我也尝试了子查询,但不确定是否可行:
WITH g AS (
SELECT field1,
count(*) AS num_polygons,
table1.geom
FROM table1
GROUP BY table1.field1, table1.geom
)
SELECT g.field1,
att.field2,
st_intersection(g.geom, att.geom) AS intersect_geom,
st_area(g.geom) AS geom_area,
st_area(st_intersection(g.geom, att.geom)) AS intersect_area
FROM g
JOIN table2 att ON g.geom && att.geom
WHERE ST_IsValid(att.geom) AND ST_IsValid(g.geom);
我想提高性能,如有任何帮助,我们将不胜感激。
此答案假定几何列已正确编入索引,例如使用 gist
:
CREATE INDEX idx_tb1_geom ON table1 USING gist (geom);
CREATE INDEX idx_tb2_geom ON table2 USING gist (geom);
您的查询在空间上连接了包含 400 和 2500 万条记录的两个表 没有 WHERE
子句,这意味着它可能 return 两个表的笛卡尔积。这是一个巨大的结果集!
我使用包含 403 条记录和 table2
500 万条记录的 table1
复制了您的环境,并且它的工作速度非常快。为了说明我的观点,如果我们简单地计算重叠的几何数量(而不实际检索它们),查询运行得非常快:
EXPLAIN (ANALYSE,COSTS OFF)
SELECT count(att.*)
FROM table1 g
JOIN table2 att ON g.geom && att.geom;
QUERY PLAN
---------------------------------------------------------------------------------------------------
Aggregate (actual time=516.299..516.300 rows=1 loops=1)
-> Nested Loop (actual time=6.118..501.909 rows=281212 loops=1)
-> Seq Scan on table1 g (actual time=0.060..0.312 rows=403 loops=1)
-> Bitmap Heap Scan on table2 att (actual time=0.187..1.198 rows=698 loops=403)
Recheck Cond: (g.geom && geom)
Heap Blocks: exact=279398
-> Bitmap Index Scan on idx_tb2_geom (actual time=0.108..0.108 rows=698 loops=403)
Index Cond: (geom && g.geom)
Planning Time: 0.505 ms
Execution Time: 519.337 ms
请注意,查询在 519ms 中过滤了 281212 个几何图形,这对于数据量而言并不是最差的性能。但是,如果您决定检索这 281212 个几何图形,情况就会大不相同,因为您会遇到其他瓶颈,例如可用内存和网络速度。
一条经验法则:永远不要将数据带到软件中,而是将软件带到数据中!这意味着在将数据加载到应用程序之前,您应该尽可能多地在数据库中处理数据。