postgresql - 自动清空后的索引大小
问题描述
再会。我正在阅读与 Vacuum 过程和 Reindex 例程相关的 Postgres 官方文档。有些句子对我来说不清楚,所以我想澄清一下。(版本 12 的 Postgres 文档)
首先。我确实了解 autovacuum 检查表中的死元组,将它们的位置存储在称为“maintenance_work_mem”的特殊内存中,然后当该内存已满时,真空删除所有索引中引用这些位置的相应页面。关于重新索引的文档说
完全为空的 B 树索引页将被回收以供重新使用。但是,仍然存在空间使用效率低下的可能性:如果页面上除少数索引键之外的所有索引键都已删除,则该页面仍保持分配状态
问题是。如果“页面保持分配状态”,那么这是否意味着 autovacuum 不会将索引内已删除页面的物理空间返回给操作系统?例如索引需要 1 GB 的内存。我从表中删除了除一行以外的所有内容并运行了真空。在这种情况下,索引仍将占用 1 Gb 的内存。我对吗?
解决方案
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)
推荐阅读
- javascript - 如何检查单元格内的元素是否被检查?
- github - E0020 标识符“睡眠”未定义 Visual Studio 2019
- php - 使用 PHP 管理 Google Cloud Storage 缓存
- angular - 从 Angular-Calendar-Year-View 关闭微调器 [https://www.npmjs.com/package/angular-calendar-year-view]
- c - 错误:成员引用基类型 'struct configuration (char *)' 不是结构或联合
- javascript - 如何使用javascript将小时和分钟转换为分钟?
- flutter - 无法在 ChatScreen 颤动中获取用户聊天消息
- python - 如何使用列表理解从用户那里获取有效和特定数量的输入,就像下面在 python 中给出的语句一样
- javascript - 显示错误 l"cannot read property 'servers' of undefined"
- angular - 在 APP_INITIALIZER 完成之前触发了 Angular 服务构造函数