重建索引reindex
专栏内容:
- postgresql使用入门基础
- 手写数据库toadb
- 并发编程
个人主页:我的主页
管理社区:开源数据库
座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.
文章目录
概述
前面几章节有关索引的内容,介绍了索引的原理,根据索引算法不同列出了postgresql支持的五大索引类型,还有扩展索引类型;同时分几节介绍了创建不同用途的索引,如部分索引,唯一性索引,基于表达式的索引等等,满足不同场景需求。
之前这些内容,都是分享索引的用法,索引在使用的过程中,不同的插入,删除会使得索引存储变得越来越稀疏,在查询索引数据时,需要从磁盘读取的数据量越来越多,使得索引查询优势不再明显。
这就涉及到本节的内容-重建索引reindex,索性数据需要定期的进行维护,及时的消除索引数据的膨胀,使得索引查询效率能够保持。
命令介绍
索引如何来维护呢? 我们来看一下reindex命令的语法。
reindex工具
有两种途径来执行reindex命令,
- 一种是通过工具来执行
在安装目录的bin目录下,会有名称为
reindexdb
的可执行工具,可以查看它的帮助进行操作。
[zpzhao@hatch bin]$ ./reindexdb --help
reindexdb reindexes a PostgreSQL database.
Usage:
reindexdb [OPTION]... [DBNAME]
Options:
-a, --all reindex all databases
--concurrently reindex concurrently
-d, --dbname=DBNAME database to reindex
-e, --echo show the commands being sent to the server
-i, --index=INDEX recreate specific index(es) only
-j, --jobs=NUM use this many concurrent connections to reindex
-q, --quiet don't write any messages
-s, --system reindex system catalogs only
-S, --schema=SCHEMA reindex specific schema(s) only
-t, --table=TABLE reindex specific table(s) only
--tablespace=TABLESPACE tablespace where indexes are rebuilt
-v, --verbosewrite a lot of output
-V, --version output version information, thenexit
-?, --help show this help, thenexit
Connection options:
-h, --host=HOSTNAME database server host or socket directory
-p, --port=PORT database server port
-U, --username=USERNAME user name to connect as
-w, --no-password never prompt for password
-W, --password force password prompt
--maintenance-db=DBNAME alternate maintenance database
Read the description of the SQL command REINDEX for details.
Report bugs to <[email protected]>.
PostgreSQL home page: <https://www.postgresql.org/>
- 一种是通过SQL命令来执行
登陆客户端后,SQL命令中
reindex
可以进行重建索引。
下面重点介绍一下SQL命令的语法与使用方法,工具命令也同样有这些选择。
SQL命令语法
REINDEX [( option, ...)]{ INDEX | TABLE | SCHEMA | DATABASE | SYSTEM }
name;
语法说明
- option可选项,有三个选项供选择:
- CONCURRENTLY , 有此选项时,采用并行重建的方式,具体后面介绍;
- TABLESPACE new_tablespace,指定重建后的索引存储的表空间,如果不指定,则为当前表空间;
- VERBOSE , 打印一些进度信息;
- 指定索引的范围,可以选择如下内容之一:
- index, 具体某一个索引,后面name 为索引的名称;
- table, 重建指定表上的所有索引,name 为表名;
- schema, 重建指定schema上的所有索引, name为对应的schema名称;
- database, 重建指定database上的所有索引, name为指定的database, 如不指定name时,为当前登陆的database;
- system, 重建系统表的索引,在指定database时,会跳过系统表的索引,此时可以不指定name。
案例分析
下面一起来看下如何维护索引,案例使用的表是products产品表,定义如下。
CREATETABLE products (
product_id INTPRIMARYKEY,
product_name VARCHAR(255)NOTNULL,
price DECIMAL(10,2)NOTNULL,
category VARCHAR(255));
除了主键索引外,为了方便观测,在product_name上新增了一个idx_proname的默认索引类型的索引。
查看索引大小
我们先来看一下索引数据的大小。
postgres=>createindex idx_proname on products (product_name );CREATEINDEX
postgres=>select pg_size_pretty(pg_total_relation_size('idx_proname'));
pg_size_pretty
----------------3104 kB
(1row)
这里使用postgresql 内置函数 pg_total_relation_size 来获取索引的数据大小;
pg_size_pretty函数,是把字节数转换为计量单位(KB,MB,GB等等)。
可以看到,初建之后,索引大小为3104KB, 下面我们模拟使用。
更新索引键的列,使得索引也会发生变化,让产品名后面再追加一个产品ID,生成新的产品名称。
postgres=>update products set product_name = product_name || product_id ;UPDATE100000
经过update操作,所有行都会被更新了一遍,理论上每条数据的索引都要新生成一次。
下面再来看索引数据的大小。
postgres=>select pg_size_pretty(pg_total_relation_size('idx_proname'));
pg_size_pretty
----------------6184 kB
(1row)
果然,索引数据翻了一倍还多一些。
为什么比一倍还多呢? 这里因为Btree索引算法,是一个树形结构,叶子节点才会存储真正的键值,那么随着叶子节点的增多,树的中间层节点也会增加,所以就会比实际数据多占一些空间。
经过长时间使用后,索引数据确实膨胀了不少,所以必须定期进行维护,下面看看维护后的效果。
postgres=> reindex index idx_proname ;
REINDEX
执行SQL语句
reindex
,指定维护的索引idx_proname, 很快就执行完成了。
然后再看一下索引数据的大小,是不是恢复了呢?
postgres=>select pg_size_pretty(pg_total_relation_size('idx_proname'));
pg_size_pretty
----------------3104 kB
(1row)
不出所料,数据行数没有发生变化,经过重建后,索引大小与新建时一模一样,太神奇了,又可以开心玩耍了。
总结
索引虽好,但不要贪哟,还需要时常维护的。 本文介绍了索引维护命令reindex, 它有两种命令形态,一是工具方式执行,另一种是SQL的方式。
通过一个案例,可以清晰的看到,经过一系列模拟使用后,索引数据明显发生了膨胀,势必造成索引的磁盘IO增加,影响索引的性能,经过reindex之后,又恢复了它初建的大小。
结尾
非常感谢大家的支持,在浏览的同时别忘了留下您宝贵的评论,如果觉得值得鼓励,请点赞,收藏,我会更加努力!
作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。
注:未经同意,不得转载!
版权归原作者 韩楚风 所有, 如有侵权,请联系我们删除。