通过GIST索引获得多边形查询中点的性能


10

我有两个表:locations(id,region_id,the_geom)和regions(id,the_geom)。对于每个定位点,我想确定其位于的区域:

UPDATE locations SET region_id = 
 (SELECT id FROM regions 
  WHERE ST_Within(locations.the_geom,regions.the_geom)
 );

在位置点上建立GIST索引是否有意义?我将在区域多边形上建立索引,但是不确定这些点。会加快查询速度吗?

Answers:


14

简短的答案:否。通过这种类型的UPDATE查询,我们正在更新locations(“ Seq Scan”)中的每一行,并且the_geomin 上的GiST索引regions足以帮助限制行,以匹配ST_Within条件从中配对右行regions


更长的答案:弄清楚这一点的魔力是比较您从解释查询中得到的结果。在pgAdmin III中,查询编辑器顶部有一个“解释查询”按钮,或者在pgsql中,只需在查询前加上“解释”即可:

postgis=# explain UPDATE locations SET region_id =
postgis-#  (SELECT id FROM regions
postgis(#   WHERE ST_Within(locations.the_geom, regions.the_geom)
postgis(#  );
                                         QUERY PLAN
--------------------------------------------------------------------------------------------
 Seq Scan on locations  (cost=0.00..8755.54 rows=1000 width=110)
   SubPlan 1
     ->  Index Scan using regions_gist_the_geom on regions  (cost=0.00..8.52 rows=1 width=4)
           Index Cond: ($0 && the_geom)
           Filter: _st_within($0, the_geom)
(5 rows)

您无需了解这里出现的所有问题。在这里看到的关键是在最里面的部分(子计划1),它指示“索引”(=使用索引,可以大大加快速度),而不是“序列扫描”(=顺序扫描,即检查每个行以查看它是否在其中,这可能会更慢)。如果在上添加/删除GiST索引locations,则说明查询的输出完全相同,因此查询性能应相同。

但是,如果您做一些愚蠢的事情,并从中删除了GiST索引regions,则您会从与上述相同的查询中看到不同的查询计划:

                             QUERY PLAN
---------------------------------------------------------------------
 Seq Scan on locations  (cost=0.00..74288.00 rows=1000 width=110)
   SubPlan 1
     ->  Seq Scan on regions  (cost=0.00..74.05 rows=1 width=4)
           Filter: (($0 && the_geom) AND _st_within($0, the_geom))
(4 rows)

在这两个解释性查询之间要看的重要一件事是最大成本估算..在这里将74.05与之前的8.52进行对比,因此您希望此查询的速度较慢。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.