尽管没有创建新数据,Postgres / PostGIS SQL更新仍严重抨击硬盘

时间:2013-03-17 21:55:50

标签: sql postgresql sql-update gis postgis

我有一张370万行的表格。它有一个布尔值(下面称为 bool_value ),它已经包含了所有行的值。

我正在使用此查询来修改 bool_value

DROP INDEX IF EXISTS table_bool_value_idx;

UPDATE table
SET bool_value = (
st_contains(st_setsrid((SELECT geom FROM gis.cntys04_3081 WHERE gid=57), 3081), the_geom)
AND st_contains((SELECT geom_3081 FROM gis.stratmap_city_poly_v4 WHERE gid = 127), the_geom)
);

到目前为止,此查询已运行了大约12个小时。在整个过程中,我的硬盘驱动器具有100%的利用率。

我不明白这个硬盘驱动器的使用情况,因为该表在过去一个月内已被清理过, bool_value 已经有了每行的记录,我放弃了索引。 gis 命名空间中的两个表(在查询中引用)都在其 gid 字段上编制索引。那些 gis 命名空间表不是视图。它们只是我使用PostGIS的 PostGIS 2.0 Shapefile和DBF Loader Exporter 导入的SHP。计算机上没有其他任何重大事件发生。

每个任务管理器,CPU利用率几乎为零,即使在postgres.exe进程中也是如此。我认为这是由于极端的硬盘驱动器活动。

计算机总共有8GB。几乎一半是免费的。有14个并发的postgres.exe进程打开,它们各有2.8 MB到9 MB。只有一个过程显示出很多活动。

以下是我想知道的一件事:来自第二个 st_contains geom_3081 长度为1.0 MB。这是一个PostGIS MULTIPOLYGON,代表德克萨斯州达拉斯的城市范围。我想这将被Windows磁盘缓存缓存,以防止重复的硬盘访问。 geom_3081 未编入索引,但我不明白为什么索引它会有所帮助,因为它不用于确定返回哪些行; gid 字段正在这样做。

1 个答案:

答案 0 :(得分:1)

无论这里存在哪些其他问题(并且很可能还有其他问题),这应该会使您的查询更快:

UPDATE table t
SET    bool_value = x.new_bool
FROM (
   SELECT table_id
         ,(st_contains(st_setsrid
               ((SELECT geom FROM gis.cntys04_3081 WHERE gid=57)
                 ,3081
               ), the_geom)
           AND st_contains
              ((SELECT geom_3081 FROM gis.stratmap_city_poly_v4 WHERE gid = 127)
              ,the_geom
              )
          ) AS new_bool
   FROM   table
   ) upd
WHERE  t.table_id = upd.table_id
AND    t.bool_value IS DISTINCT FROM x.new_bool;

table_id是此处的主要关键。

校长是避免空更新。而且由于我们讨论的是一个布尔值,很可能,你有很大一部分更新实际上没有改变任何东西。但是这样的更新仍然会导致磁盘活动,因为旧行被标记为已过时,插入了一个新的(未更改的)行。

要弄清楚还有什么问题,你可以走已经证实的分而治之路径:附加到子查询:

ORDER  BY table_id
LIMIT  10
OFFEST 0

如果有这种情况,请使用更大的切片继续递增LIMITOFFSET。只要性能保持良好,就增加切片的大小。一定要在不同的交易中运行。

这可能会避免缓存问题(如磁盘负载过多所示),也可以避免出现任何并发问题。如果更新几行仍然很慢,那么肯定还有其他问题。


至于:

  

我不明白这个硬盘驱动器的使用率如表所示   在过去一个月内被吸尘,

这是一种误解。 VACUUM 通常会使UPDATE更快(除了表格膨胀的极端情况)。也许更慢。更糟糕的是VACUUM FULL。这将删除所有死元组,并使用尽可能紧密的实时元组打包数据页。

以下UPDATE无法使用HOT updates,因为个别数据页面上没有“摆动空间”。如果您有大量更新,请考虑fillfactor的较低设置。

在dba.SE herehere以及here上查找有关这些密切相关问题的更多信息和链接。