更新不使用索引 postgres

Posted

技术标签:

【中文标题】更新不使用索引 postgres【英文标题】:update not using index postgres 【发布时间】:2014-04-15 20:04:53 【问题描述】:

我正在尝试优化查询。我正在更新的表 vwml_premelissa 有 350 万条记录。我有第二个表(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 窗口

【问题讨论】:

您的统计数据是最新的吗 (analyze)?您也可以尝试加入而不是 IN 【参考方案1】:

我不是 DBMS 专家,自从我在 PostgreSQL 中使用任何时间以来已经有几年了,但是在某些 RDBMS 中,如果引擎认为它必须执行表扫描,查询并不总是使用索引反正。例如,如果vwml_threes 具有高基数并且行数与vwml_premelissa 中的相似,那么引擎可能会认为执行表扫描与尝试对@987654323 中的每条记录执行索引查找一样有效@。

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

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

【讨论】:

以上是关于更新不使用索引 postgres的主要内容,如果未能解决你的问题,请参考以下文章

NSFetchedResultsController 不更新 UITableView 的部分索引

仅当更新前不存在用户时如何将用户添加到索引 Elasticsearch

如何使用 Firebase 实时数据库在不知道 Android 索引的情况下更新 ArrayList 中的元素?

是否可以只更新 pypi 索引中的详细信息,而不重新创建包?

由于设置不正确,触发器内部更新失败

sphinx主索引和增量索引实时更新