首页 > 解决方案 > 自动清空后的索引大小

问题描述

再会。我正在阅读与 Vacuum 过程和 Reindex 例程相关的 Postgres 官方文档。有些句子对我来说不清楚,所以我想澄清一下。(版本 12 的 Postgres 文档)

首先。我确实了解 autovacuum 检查表中的死元组,将它们的位置存储在称为“maintenance_work_mem”的特殊内存中,然后当该内存已满时,真空删除所有索引中引用这些位置的相应页面。关于重新索引的文档

完全为空的 B 树索引页将被回收以供重新使用。但是,仍然存在空间使用效率低下的可能性:如果页面上除少数索引键之外的所有索引键都已删除,则该页面仍保持分配状态

问题是。如果“页面保持分配状态”,那么这是否意味着 autovacuum 不会将索引内已删除页面的物理空间返回给操作系统?例如索引需要 1 GB 的内存。我从表中删除了除一行以外的所有内容并运行了真空。在这种情况下,索引仍将占用 1 Gb 的内存。我对吗?

标签: postgresqlreindexvacuum

解决方案


VACUUM 是(但 VACUUM FULL 不是):

select version();
                                                 version                                                 
---------------------------------------------------------------------------------------------------------
 PostgreSQL 12.3 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39), 64-bit
(1 row)

create table t(s text);
CREATE TABLE

insert into t select generate_series(1,300000)::text;
INSERT 0 300000

select pg_size_pretty(pg_table_size('t'));
 pg_size_pretty 
----------------
 10 MB
(1 row)

create index on t(s);
CREATE INDEX

select pg_size_pretty(pg_indexes_size('t'));
 pg_size_pretty 
----------------
 6600 kB
(1 row)

delete from t where s <> '1';
DELETE 299999

select count(*) from t;
 count 
-------
     1
(1 row)

select pg_size_pretty(pg_table_size('t'));
 pg_size_pretty 
----------------
 10 MB
(1 row)

select pg_size_pretty(pg_indexes_size('t'));
 pg_size_pretty 
----------------
 6600 kB
(1 row)

vacuum t;
VACUUM
select pg_size_pretty(pg_table_size('t'));
 pg_size_pretty 
----------------
 48 kB
(1 row)

select pg_size_pretty(pg_indexes_size('t'));
 pg_size_pretty 
----------------
 6600 kB
(1 row)

vacuum full t;
VACUUM
select pg_size_pretty(pg_table_size('t'));
 pg_size_pretty 
----------------
 16 kB
(1 row)

select pg_size_pretty(pg_indexes_size('t'));
 pg_size_pretty 
----------------
 16 kB
(1 row)

REINDEX 没有:

select version();
                                                 version                                                 
---------------------------------------------------------------------------------------------------------
 PostgreSQL 12.3 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39), 64-bit
(1 row)

create table t(s text);
CREATE TABLE

insert into t select generate_series(1,300000)::text;
INSERT 0 300000

select pg_size_pretty(pg_table_size('t'));
 pg_size_pretty 
----------------
 10 MB
(1 row)

create index on t(s);
CREATE INDEX

select pg_size_pretty(pg_indexes_size('t'));
 pg_size_pretty 
----------------
 6600 kB
(1 row)

delete from t where s <> '1';
DELETE 299999

select count(*) from t;
 count 
-------
     1
(1 row)

select pg_size_pretty(pg_table_size('t'));
 pg_size_pretty 
----------------
 10 MB
(1 row)

select pg_size_pretty(pg_indexes_size('t'));
 pg_size_pretty 
----------------
 6600 kB
(1 row)

reindex table t;
REINDEX

select pg_size_pretty(pg_table_size('t'));
 pg_size_pretty 
----------------
 10 MB
(1 row)

select pg_size_pretty(pg_indexes_size('t'));
 pg_size_pretty 
----------------
 16 kB
(1 row)

推荐阅读