更新不使用索引postgres

时间:2014-04-15 20:04:53

标签: sql postgresql-9.2

我正在尝试优化查询。我更新的表vwml_premelissa有3.5mil记录。我有第二个表(50k记录),指定需要更新的记录。

" vin" vwml_premelissa上有一个唯一索引。列。

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_premelissa进行seq扫描,而不是使用索引来查找需要更新的记录?

postgres 9.2 windows

1 个答案:

答案 0 :(得分:0)

我不是DBMS专家,自从我花了一些时间在PostgreSQL上已经过了几年,但在一些RDBMS中,如果引擎认为它并不总是使用索引。 #39;无论如何都要进行表扫描。例如,如果vwml_threes具有高基数且行数与vwml_premelissa中的行数相似,则引擎可能会认为执行表扫描与尝试执行的效率相同vwml_threes中每条记录的索引查找。

您可以尝试包含其他条件,例如按日期分块,然后迭代这些块,直到完整更新完成。显然,如果您希望看到性能增益,那么这些标准也需要编入索引,因此您的总查询成本将包括添加缺失索引,这对于一次性查询可能没有意义。

我有兴趣听听这个解释是否适用于PostgreSQL - 我很可能错了。