为什么仅索引扫描需要这么长时间?

y43*_*34y 9 sql database postgresql postgresql-9.3

为什么执行我的简单查询

select count(this_.Id) as y0_ from Activity this_
Run Code Online (Sandbox Code Playgroud)

需要这么长时间(这次超过10分钟)?

这是查询计划(EXPLAIN ANALYZE的输出):

QUERY PLAN  
 Aggregate (cost=854047.36..854047.37 rows=1 width=4)
> (actual time=728525.277..728525.277 rows=1 loops=1)   
->  Index Only
> Scan using activity_pkey on activity this_  (cost=0.56..805401.87
> rows=19458196 width=4) (actual time=36.961..725381.557 rows=19517989
> loops=1)  
> Heap Fetches: 10351403  
Total runtime: 728533.529 ms
Run Code Online (Sandbox Code Playgroud)

和PostgreSql版本:

PostgreSQL 9.3.5 on x86_64-unknown-linux-gnu, compiled by gcc (Debian 4.7.2-5) 4.7.2, 64-bit
Run Code Online (Sandbox Code Playgroud)

在Id字段中,索引也在这里:

ALTER TABLE public.activity
ADD CONSTRAINT activity_pkey 
PRIMARY KEY (id);
Run Code Online (Sandbox Code Playgroud)

Ego*_*gov 5

PostgreSQL中的仅索引扫描有时必须查看表(堆),因为索引页面不包含有关元组可见性的信息。那就是从索引中获取了多少行:

(实际...行= 19517989

这就是在堆中重新检查多少行:

堆获取:10351403

为了加快速度,您应该在桌子上抽真空: vacuum Activity

Vacuum将更新可见性图,之后,“仅索引扫描”将只能使用(几乎)索引页执行。