更新不使用索引 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 中的元素?