暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MogDB索引膨胀的实验

由迪 2024-01-20
145

原作者:姜殿斌

看到一个说法: 如果数据发生大量删除后,索引页面上的索引键将被删除,导致索引页面数量的减少,造成索引膨胀。重建索引可回收浪费的空间。

我们通过下面的实验,验证这个说法是否正确。

1、实验环境

1)创建表:

[omm@node1 ~]$ gsql -r`
`gsql ((MogDB 5.0.3 build 86d963ad) compiled at 2023-10-13 09:17:48 commit 0 last mr 1804 )`
`Non-SSL connection (SSL connection is recommended when requiring high-security)`
`Type "help" for help.
MogDB=#

drop table if exists test1;
create table test1(
id int primary key,
number1 int,
number2 int);

2)插入数据、创建索引:

insert into test1 select i,i,0 from generate_series(1,1000000) as i;
create index test1_number1_idx on test1(number1);

2、实验过程

1)查看表和索引所占的块数

MogDB=# \x`
`Expanded display is on.
MogDB=# select relname,reltype,relpages,reltuples from pg_class where relname='test1';`
`-[ RECORD 1 ]------`
`relname  | test1`
`reltype  | 17123`
`relpages  | 5406`
`reltuples | 1000000
MogDB=# select relname,reltype,relpages,reltuples from pg_class where relname='test1_number1_idx';`
`-[ RECORD 1 ]--------------------`
`relname  | test1_number1_idx`
`reltype  | 0`
`relpages  | 2752`
`reltuples | 1000000

2)删除表数据后,再次查看表和索引锁占的块数:

MogDB=# delete from test1 where id>100;`
`DELETE 999900`
`MogDB=# select relname,reltype,relpages,reltuples from pg_class where relname='test1';`
`-[ RECORD 1 ]----`
`relname  | test1`
`reltype  | 17081`
`relpages  | 5406`
`reltuples | 100
MogDB=# select relname,reltype,relpages,reltuples from pg_class where relname='test1_number1_idx';
-[ RECORD 1 ]----------------`
`relname  | test1_number1_idx`
`reltype  | 0`
`relpages  | 2752`
`reltuples | 100
说明:
   删除数据后,没有新数据插入时,表、索引的占用的页面数均不变。

3)autovacuum后,查看表和索引锁占的块数:

由于默认打开了autovacuum,所以,系统会自动出发autovacuum操作,不用手动 vacuum 。

当然,也可以手动执行vacuum test1。

MogDB=# select relname,reltype,relpages,reltuples from pg_class where relname='test1';
-[ RECORD 1 ]----
relname | test1
reltype | 17081
relpages | 1
reltuples | 100

说明:表的使用空间从5406减少到1个page。

MogDB=# select relname,reltype,relpages,reltuples from pg_class where relname='test1_number1_idx';
-[ RECORD 1 ]--------------------
relname | test1_number1_idx
reltype | 0
relpages | 2752
reltuples | 100
说明:索引的使用空间则没有变化,仍是2752个pages 。

4)重建索引,解决索引膨胀。

查看索引锁占的块数:

MogDB=# reindex table test1;`
`REINDEX`
`MogDB=# select relname,reltype,relpages,reltuples from pg_class where relname='test1_number1_idx';`
`-[ RECORD 1 ]--------------------`
`relname  | test1_number1_idx`
`reltype  | 0`
`relpages  | 2`
`reltuples | 100

说明: reindex后,索引占用的块数从2752减少到2pages。

4、结论:

​ 删除数据后,没有新数据插入时,索引页面数不变。

**原因:**是在Astore引擎中,删除仅仅在块中做了标记,并未真正删除。

reindex重建索引后,才真正删除,占用的块数才变小,即通过重建索引,解决索引膨胀问题。

通过实验验证, 文章开头提到的说法不是十分准确。可以改为:

“如果数据发生大量删除后,索引页面上的索引键将被删除,索引数量变小,但是索引占用页面的数量未变,造成索引膨胀。重建索引可回收浪费的空间。”

5、附录:

1、pg_class说明:
参考:https://docs.mogdb.io/zh/mogdb/v5.0/PG_CLASS

说明:relpages,以页(大小为BLCKSZ)为单位的此表在磁盘上的大小,它只是优化器用的一个近似值。但是不影响观测存储空间的变化。

2、实验中涉及的autovacuum的参数:

MogDB=# show track_counts;`
`-[ RECORD 1 ]+---`
`track_counts | on
MogDB=# show autovacuum_max_workers;`
`-[ RECORD 1 ]----------+---`
`autovacuum_max_workers | 10
MogDB=# show autovacuum_mode;`
`-[ RECORD 1 ]---+----`
`autovacuum_mode | mix
MogDB=# show  autovacuum;`
`-[ RECORD 1 ]--`
`autovacuum | on
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论