更新不使用索引postgres



我正在尝试优化一个查询。我正在更新的表vwml_premilisa有350万条记录。我有第二个表(50k条记录),它指定了哪些记录需要更新。

在"vin"列上的vwml_remelissa上有一个唯一的索引。

CREATE UNIQUE INDEX pkey_vwml_premelissa
  ON extras.vwml_premelissa
  USING btree
  (vin COLLATE pg_catalog."default");

查询。。。

update extras.vwml_premelissa 
    set suppress = 'THREE' where vin in (select vin from extras.vwml_threes) 

在我的开发箱上要花一个多小时。当我对查询进行解释时,我会得到

Update on vwml_premelissa  (cost=1837.07..412393.58 rows=52892 width=182)
  ->  Hash Semi Join  (cost=1837.07..412393.58 rows=52892 width=182)
        Hash Cond: ((vwml_premelissa.vin)::text = (vwml_threes.vin)::text)
        ->  Seq Scan on vwml_premelissa  (cost=0.00..219004.32 rows=3685132 width=176)
        ->  Hash  (cost=865.92..865.92 rows=52892 width=24)
              ->  Seq Scan on vwml_threes  (cost=0.00..865.92 rows=52892 width=24)

为什么postgres坚持对vwml_remelissa进行seq扫描,而不是使用索引来定位需要更新的记录?

postgres 9.2 windows

我不是DBMS专家,我已经有几年没有在PostgreSQL中工作了,但在一些RDBMS中,如果引擎认为无论如何都必须执行表扫描,那么查询并不总是使用索引。例如,如果vwml_threes具有高基数和类似于vwml_premelissa中的行数,则引擎可能会决定,对vwml_threes中的每个记录执行索引查找和执行表扫描一样有效。

您可以尝试包含额外的标准,例如按日期进行分块,然后在这些分块上迭代,直到您的完整更新完成。显然,如果您希望看到性能提升,也需要对这些条件进行索引,因此您的总查询成本将包括添加丢失的索引,这对于一次性查询来说可能没有意义。

我很想知道这个解释是否适用于PostgreSQL——很可能我错了。

最新更新