我在 PostgreSQL 9.3 数据库中有一个大表(大约 10M 条记录),我正在尝试运行一个简单的更新语句:
UPDATE mytable SET fresh = null WHERE fresh = true;
它已经运行了一个多小时,看不到任何尽头。
但是,我知道:
SELECT count(*) FROM mytable WHERE fresh = true;
它在几秒钟内运行,它只会影响 7000 条记录。
为什么我的更新需要这么长时间?我的数据库中没有任何触发器,并且该fresh
列的索引为:
CREATE INDEX mytable_fresh ON mytable USING btree (fresh);
运行EXPLAIN UPDATE mytable SET fresh = null WHERE fresh = true
给出:
Update on mytable (cost=0.00..455553.18 rows=9525759 width=167)
-> Seq Scan on mytable (cost=0.00..455553.18 rows=9525759 width=167)
Filter: fresh
我是否正确,它正在扫描所有 950 万条记录而不使用索引?如果是这样,我该如何解决这个问题?
编辑:我的fresh
列是可为空的布尔类型。我为该true
值添加了一个部分索引,这大大加快了它的速度(22 毫秒)。不确定为什么部分索引有效而通用索引被完全忽略。我发现 Postgres 中的这种利基行为很常见,并且对于大型数据仓库项目非常令人沮丧。