索引膨胀

对于索引,随着业务不断的增删改,会造成膨胀,尤其Btree索引,也会涉及索引分裂、合并等,导致索引访问效率降低、维护成本增加。另外,索引页的复用与HEAP PAGE不一样,因为索引的内容是有序结构,只有符合顺序的ITEM才能插入对应的PAGE中,不像HEAP TUPLE,只要有空间就可以插入。index page无论在任何位置,都不能从磁盘删除,因此索引变大后,不能回收空间,除非vacuum full。所以索引膨胀后,通常需要重建索引来回收索引空间。

此外,对于B树索引,新构建的索引比多次更新的索引访问速度稍快,因为逻辑上相邻的页面通常在新构建索引中也是物理上相邻的。为了提高访问速度,定期重新B_Tree 索引可能是值得的。

对于重建索引,REINDEX在任何情况下都可以安全方便地使用。默认情况下,该命令需要ACCESS EXCLUSIVE锁。可以使用CONCURRENTLY选项创建索引,该选项只需要SHARE UPDATE EXCLUSIV锁,不阻塞读写。

索引膨胀的原因:

1.大量删除发生后,导致索引页面稀疏,降低了索引使用效率。

2.长时间运行的事务,阻止了vacuum对表的清理工作,因而导致页面稀疏状态一直保持。

3.索引字段乱序写入,导致索引频繁分裂,使得索引页并不是百分百填满,所以膨胀。

查询获取每个表的行数、索引以及有关这些索引的一些信息:

    1. SELECT
      1. pg_class.relname,
        1. pg_size_pretty(pg_class.reltuples::bigint) AS rows_in_bytes,
          1. pg_class.reltuples AS num_rows,
            1. COUNT(*) AS total_indexes,
              1. COUNT(*) FILTER ( WHERE indisunique) AS unique_indexes,
                1. COUNT(*) FILTER ( WHERE indnatts = 1 ) AS single_column_indexes,
                  1. COUNT(*) FILTER ( WHERE indnatts IS DISTINCT FROM 1 ) AS multi_column_indexes
                    1. FROM
                      1. pg_namespace
                        1. LEFT JOIN pg_class ON pg_namespace.oid = pg_class.relnamespace
                          1. LEFT JOIN pg_index ON pg_class.oid = pg_index.indrelid
                            1. WHERE
                              1. pg_namespace.nspname = 'public' AND
                                1. pg_class.relkind = 'r'
                                  1. GROUP BY pg_class.relname, pg_class.reltuples
                                    1. ORDER BY pg_class.reltuples DESC;
                                  1.  
                                    1. SELECT
                                      1. t.schemaname,
                                        1. t.tablename,
                                          1. c.reltuples::bigint AS num_rows,
                                            1. pg_size_pretty(pg_relation_size(c.oid)) AS table_size,
                                              1. psai.indexrelname AS index_name,
                                                1. pg_size_pretty(pg_relation_size(i.indexrelid)) AS index_size,
                                                  1. CASE WHEN i.indisunique THEN 'Y' ELSE 'N' END AS "unique",
                                                    1. psai.idx_scan AS number_of_scans,
                                                      1. psai.idx_tup_read AS tuples_read,
                                                        1. psai.idx_tup_fetch AS tuples_fetched
                                                          1. FROM
                                                            1. pg_tables t
                                                              1. LEFT JOIN pg_class c ON t.tablename = c.relname
                                                                1. LEFT JOIN pg_index i ON c.oid = i.indrelid
                                                                  1. LEFT JOIN pg_stat_all_indexes psai ON i.indexrelid = psai.indexrelid
                                                                    1. WHERE
                                                                      1. t.schemaname NOT IN ('pg_catalog', 'information_schema')
                                                                        1. ORDER BY 1, 2;
                                                                      1.  

                                                                      查找重复索引,查找具有相同列集、相同操作类、表达式和谓词的多个索引,但需要人为判断需要删除的重复项:

                                                                        1. SELECT pg_size_pretty(sum(pg_relation_size(idx))::bigint) as size,
                                                                          1. (array_agg(idx))[1] as idx1, (array_agg(idx))[2] as idx2,
                                                                            1. (array_agg(idx))[3] as idx3, (array_agg(idx))[4] as idx4
                                                                              1. FROM (
                                                                                1. SELECT indexrelid::regclass as idx, (indrelid::text ||E'\n'|| indclass::text ||E'\n'|| indkey::text ||E'\n'||coalesce(indexprs::text,'')||E'\n' || coalesce(indpred::text,'')) as key
                                                                                  1. FROM pg_index) sub
                                                                                    1. GROUP BY key HAVING count(*)>1
                                                                                      1. ORDER BY sum(pg_relation_size(idx)) DESC;
                                                                                    1.  

                                                                                    查找未使用的索引:

                                                                                      1. select
                                                                                        1. indexrelid::regclass as index, relid::regclass as table
                                                                                          1. from
                                                                                            1. pg_stat_user_indexes
                                                                                              1. JOIN pg_index USING (indexrelid)
                                                                                                1. where
                                                                                                  1. idx_scan = 0 and indisunique is false;
                                                                                                1.  

                                                                                                有些场景,重建索引后,索引就变小了。通常这种情况是索引字段乱序写入,导致索引频繁分裂,使得索引页并不是百分百填满,密度低,索引页面浪费。

                                                                                                索引碎片模拟

                                                                                                  1. 乱序写入:
                                                                                                      1. test=# create table t_split(id int);
                                                                                                        1. CREATE TABLE
                                                                                                          1. test=# create index idx_split on t_split (id);
                                                                                                            1. CREATE INDEX
                                                                                                              1. test=# insert into t_split select random()*1000000 from generate_series(1,1000000);
                                                                                                                1. INSERT 0 1000000
                                                                                                                  1. test=# \di+ idx_split
                                                                                                                    1. List of relations
                                                                                                                      1. Schema | Name | Type | Owner | Table | Size | Description
                                                                                                                        1. --------+-----------+-------+--------+---------+-------+-------------
                                                                                                                          1. public | idx_split | index | system | t_split | 30 MB |
                                                                                                                              1. (1 row)
                                                                                                                                  1. 顺序写入:
                                                                                                                                      1. test=# truncate t_split ;
                                                                                                                                        1. TRUNCATE TABLE
                                                                                                                                          1. test=# \di+ idx_split
                                                                                                                                            1. List of relations
                                                                                                                                              1. Schema | Name | Type | Owner | Table | Size | Description
                                                                                                                                                1. --------+-----------+-------+--------+---------+------------+-------------
                                                                                                                                                  1. public | idx_split | index | system | t_split | 8192 bytes |
                                                                                                                                                      1. (1 row)
                                                                                                                                                          1. test=# insert into t_split select generate_series(1,1000000);
                                                                                                                                                            1. INSERT 0 1000000
                                                                                                                                                              1. test=# \di+ idx_split
                                                                                                                                                                1. List of relations
                                                                                                                                                                  1. Schema | Name | Type | Owner | Table | Size | Description
                                                                                                                                                                    1. --------+-----------+-------+--------+---------+-------+-------------
                                                                                                                                                                      1. public | idx_split | index | system | t_split | 22 MB |
                                                                                                                                                                          1. (1 row)
                                                                                                                                                                              1. 先写入数据,后建索引:
                                                                                                                                                                                  1. test=# drop index idx_split ;
                                                                                                                                                                                    1. DROP INDEX
                                                                                                                                                                                      1. test=# create index idx_split on t_split (id);
                                                                                                                                                                                        1. CREATE INDEX
                                                                                                                                                                                          1. test=# \di+ idx_split
                                                                                                                                                                                            1. List of relations
                                                                                                                                                                                              1. Schema | Name | Type | Owner | Table | Size | Description
                                                                                                                                                                                                1. --------+-----------+-------+--------+---------+-------+-------------
                                                                                                                                                                                                  1. public | idx_split | index | system | t_split | 22 MB |
                                                                                                                                                                                                    1. (1 row)
                                                                                                                                                                                                          1. 业务运行久了,不断的增删改,也会导致索引碎片:
                                                                                                                                                                                                              1. test=# create table test(id int);
                                                                                                                                                                                                                1. CREATE TABLE
                                                                                                                                                                                                                  1. test=# insert into test values(generate_series(1,1000000));
                                                                                                                                                                                                                    1. INSERT 0 1000000
                                                                                                                                                                                                                      1. test=# create index idx_fragmented on test(id);
                                                                                                                                                                                                                        1. CREATE INDEX
                                                                                                                                                                                                                          1. CREATE EXTENSION kbstattuple;
                                                                                                                                                                                                                            1. 刚刚创建的索引没有碎片:
                                                                                                                                                                                                                              1. test=# \x
                                                                                                                                                                                                                                1. Expanded display is on.
                                                                                                                                                                                                                                  1. test=# SELECT * FROM pgstatindex('idx_fragmented');
                                                                                                                                                                                                                                    1. -[ RECORD 1 ]------+---------
                                                                                                                                                                                                                                      1. version | 4
                                                                                                                                                                                                                                        1. tree_level | 2
                                                                                                                                                                                                                                          1. index_size | 22609920
                                                                                                                                                                                                                                            1. root_block_no | 289
                                                                                                                                                                                                                                              1. internal_pages | 11
                                                                                                                                                                                                                                                1. leaf_pages | 2748
                                                                                                                                                                                                                                                  1. empty_pages | 0
                                                                                                                                                                                                                                                    1. deleted_pages | 0
                                                                                                                                                                                                                                                      1. avg_leaf_density | 89.93
                                                                                                                                                                                                                                                        1. leaf_fragmentation | 0
                                                                                                                                                                                                                                                              1. leaf_fragmentation的碎片率是33.33%:
                                                                                                                                                                                                                                                                1. test=# insert into test values(generate_series(1,1000000));
                                                                                                                                                                                                                                                                  1. INSERT 0 1000000
                                                                                                                                                                                                                                                                    1. test=# SELECT * FROM pgstatindex('idx_fragmented');
                                                                                                                                                                                                                                                                      1. -[ RECORD 1 ]------+---------
                                                                                                                                                                                                                                                                        1. version | 4
                                                                                                                                                                                                                                                                          1. tree_level | 2
                                                                                                                                                                                                                                                                            1. index_size | 67846144
                                                                                                                                                                                                                                                                              1. root_block_no | 289
                                                                                                                                                                                                                                                                                1. internal_pages | 39
                                                                                                                                                                                                                                                                                  1. leaf_pages | 8242
                                                                                                                                                                                                                                                                                    1. empty_pages | 0
                                                                                                                                                                                                                                                                                      1. deleted_pages | 0
                                                                                                                                                                                                                                                                                        1. avg_leaf_density | 60.06
                                                                                                                                                                                                                                                                                          1. leaf_fragmentation | 33.33
                                                                                                                                                                                                                                                                                                1. reindex之后,即可回收空间,减少碎片。
                                                                                                                                                                                                                                                                                                    1. test=# reindex index idx_fragmented;
                                                                                                                                                                                                                                                                                                      1. REINDEX
                                                                                                                                                                                                                                                                                                        1. test=# \di+ idx_fragmented
                                                                                                                                                                                                                                                                                                          1. List of relations
                                                                                                                                                                                                                                                                                                            1. -[ RECORD 1 ]---------------
                                                                                                                                                                                                                                                                                                              1. Schema | public
                                                                                                                                                                                                                                                                                                                1. Name | idx_fragmented
                                                                                                                                                                                                                                                                                                                  1. Type | index
                                                                                                                                                                                                                                                                                                                    1. Owner | system
                                                                                                                                                                                                                                                                                                                      1. Table | test
                                                                                                                                                                                                                                                                                                                        1. Size | 43 MB
                                                                                                                                                                                                                                                                                                                          1. Description |
                                                                                                                                                                                                                                                                                                                              1. test=# SELECT * FROM pgstatindex('idx_fragmented');
                                                                                                                                                                                                                                                                                                                                1. -[ RECORD 1 ]------+---------
                                                                                                                                                                                                                                                                                                                                  1. version | 4
                                                                                                                                                                                                                                                                                                                                    1. tree_level | 2
                                                                                                                                                                                                                                                                                                                                      1. index_size | 45236224
                                                                                                                                                                                                                                                                                                                                        1. root_block_no | 208
                                                                                                                                                                                                                                                                                                                                          1. internal_pages | 26
                                                                                                                                                                                                                                                                                                                                            1. leaf_pages | 5495
                                                                                                                                                                                                                                                                                                                                              1. empty_pages | 0
                                                                                                                                                                                                                                                                                                                                                1. deleted_pages | 0
                                                                                                                                                                                                                                                                                                                                                  1. avg_leaf_density | 90.01
                                                                                                                                                                                                                                                                                                                                                    1. leaf_fragmentation | 0
                                                                                                                                                                                                                                                                                                                                                  1.  

                                                                                                                                                                                                                                                                                                                                                  总结

                                                                                                                                                                                                                                                                                                                                                  通过以上方法监控索引膨胀,以及索引碎片情况,及时对索引reindex 进行碎片优化,建议不要在一个表上建太多索引,准确评估经常update的列和经常select的列,以便创建合适的索引。

                                                                                                                                                                                                                                                                                                                                                  文章知识点与官方知识档案匹配,可进一步学习相关知识
                                                                                                                                                                                                                                                                                                                                                  CS入门技能树Linux入门初识Linux32604 人正在系统学习中

                                                                                                                                                                                                                                                                                                                                                  [转帖]金仓数据库KingbaseES V8R6 索引膨胀的更多相关文章

                                                                                                                                                                                                                                                                                                                                                  1. 通过ODBC接口访问人大金仓数据库

                                                                                                                                                                                                                                                                                                                                                      国产化软件和国产化芯片的窘境一样,一方面市场已经存在性能优越的同类软件,成本很低,但小众的国产化软件不仅需要高价买入版权,并且软件开发维护成本高:另一方面,国产软件目前普遍难用,性能不稳定,Bug ...

                                                                                                                                                                                                                                                                                                                                                  2. QT 之 ODBC连接人大金仓数据库

                                                                                                                                                                                                                                                                                                                                                    QT 之 使用 ODBC 驱动连接人大金仓数据库 获取数据库驱动和依赖动态库 此操作可在人大金仓官网下载与系统匹配的接口动态库,或者从架构数据库的源码中获取驱动和依赖动态库 分别为: 驱动动态库:kd ...

                                                                                                                                                                                                                                                                                                                                                  3. 通过jmeter连接人大金仓数据库

                                                                                                                                                                                                                                                                                                                                                    某项目用的人大金仓数据库,做性能测试,需要用jmeter来连接数据库处理一批数据.jmeter连接人大金仓,做个记录. 1. 概要 在"配置元件"中添加"JDBC Con ...

                                                                                                                                                                                                                                                                                                                                                  4. linux安装国产数据库(金仓数据库,达梦数据库,南大通用数据库)

                                                                                                                                                                                                                                                                                                                                                    今天在公司做的任务是,在Linux的环境下安装三种数据库,结果一种数据库也没有安装好,首先遇到的问题是安装南大通用数据库遇到安装的第五步,就出现问题了,问题是Gbase SDK没有安装成功,以及Gba ...

                                                                                                                                                                                                                                                                                                                                                  5. Rocky4.2下安装金仓v7数据库(KingbaseES)

                                                                                                                                                                                                                                                                                                                                                    1.准备操作系统 1.1 系统登录界面 1.2 操作系统版本信息 jdbh:~ # uname -ra Linux jdbh -x86_64 # SMP Fri Dec :: CST x86_64 G ...

                                                                                                                                                                                                                                                                                                                                                  6. 润乾配置连接kingbase(金仓)数据库

                                                                                                                                                                                                                                                                                                                                                     问题背景 客户根据项目的不同,使用润乾连接的数据库类型各种各样,此文针对前几日使用润乾设计器连接kingbase金仓数据库做一个说明. kingbase金仓数据库是一款国产数据库,操作方式和配置 ...

                                                                                                                                                                                                                                                                                                                                                  7. 金仓Kingbase数据库网页数据维护分析工具

                                                                                                                                                                                                                                                                                                                                                    金仓Kingbase是优秀的国产数据库产品,在能源,政务,国防等领域广泛使用, 现在TreeSoft数据库管理系统已支持Kingbase了,直接在浏览器中就可以操作查看Kingbase数据了,十分方便 ...

                                                                                                                                                                                                                                                                                                                                                  8. DBeaver连接达梦|虚谷|人大金仓等国产数据库

                                                                                                                                                                                                                                                                                                                                                    前言 工作中有些项目可能会接触到「达梦.虚谷.人大金仓」等国产数据库,但通常这些数据库自带的连接工具使用并不方便,所以这篇文章记录一下 DBeaver 连接国产数据库的通用模版,下文以达梦为例(其他国 ...

                                                                                                                                                                                                                                                                                                                                                  9. KingbaseES V8R6备份恢复案例之---同一数据库创建不同stanza备份

                                                                                                                                                                                                                                                                                                                                                    案例说明: 在生产环境,有的应用需要调用数据库的sys_rman做备份,为了区分数据库自身的sys_rman备份和应用的备份,可以使用不同的stanza name创建备份.本案例介绍了,如何在King ...

                                                                                                                                                                                                                                                                                                                                                  10. KingbaseES V8R6备份恢复案例之--删除test数据库后sys_backup.sh备份

                                                                                                                                                                                                                                                                                                                                                    案例说明: KingbaseES V8R6通过sys_backup.sh执行物理备份,默认sys_backup.sh执行备份初始化时,需要连接test数据库进行身份的认证:在一些生产环境为了安全需求, ...

                                                                                                                                                                                                                                                                                                                                                  随机推荐

                                                                                                                                                                                                                                                                                                                                                  1. 开源云原生网关Linux Traefik本地部署结合内网穿透远程访问

                                                                                                                                                                                                                                                                                                                                                      开源云原生网关Linux Traefik本地部署结合内网穿透远程访问 前言 Træfɪk 是一个云原生的新型的 HTTP 反向代理.负载均衡软件,能轻易的部署微服务.它支持多种后端 (Docker ...

                                                                                                                                                                                                                                                                                                                                                  2. 斯坦福 UE4 C++ ActionRoguelike游戏实例教程 13.使用GameplayTag实现使用钥匙卡打开箱子

                                                                                                                                                                                                                                                                                                                                                    斯坦福课程 UE4 C++ ActionRoguelike游戏实例教程 0.绪论 概述 本篇文章将会展示Gameplay另一个用法,也就是我们最常见的使用特定道具交互特定的机关.例如本文要实现的,获得 ...

                                                                                                                                                                                                                                                                                                                                                  3. [Python急救站]含义GUI的学生管理系统

                                                                                                                                                                                                                                                                                                                                                    这个管理系统是含有GUI界面的学生管理系统,比较方便. import tkinter as tk class Student: def __init__(self, name, student_id, ...

                                                                                                                                                                                                                                                                                                                                                  4. Cesium案例解析(十)——CZML点

                                                                                                                                                                                                                                                                                                                                                    目录 1. 概述 2. 案例 3. 结果 1. 概述 CZML是Cesium中用于描述动态图形场景的JSON格式,它们的关系类似于Google Earth与KML之间的关系,一般会认为KML是一种矢量 ...

                                                                                                                                                                                                                                                                                                                                                  5. 绝了,华为云服务器“The 3”出道,每款都很能打

                                                                                                                                                                                                                                                                                                                                                    近年来,随着企业上云转型.互联网信息产业技术不断发展与革新,云服务器在主机市场逐渐占领主导地位,云服务器品牌层出不穷,各家云厂商都想占据一席之地,这也就对各云厂商的提供的云服务器算力和云端服务能力的要 ...

                                                                                                                                                                                                                                                                                                                                                  6. 从标准到开发,解读基于MOF的应用模型管理

                                                                                                                                                                                                                                                                                                                                                    摘要:为了打破技术与业务的壁垒,搭建技术与业务的桥梁,因此基于如下流程实现应用业务模型管理 ROMA ABM. 在数字经济时代,数据正在成为企业极其重要的战略性资产.在政府方面,数据第一次作为新型生产 ...

                                                                                                                                                                                                                                                                                                                                                  7. KubeEdge@MEC:Kubernetes容器生态与5G的结合

                                                                                                                                                                                                                                                                                                                                                    摘要:边缘计算技术快速发展,5G MEC边云协同成为最新的发展趋势. 前言 边缘计算技术快速发展,5G MEC进入商业部署快车道,边云协同成为MEC的普遍诉求,KubeEdge社区洞悉这一趋势,按照C ...

                                                                                                                                                                                                                                                                                                                                                  8. vue2升级vue3:Vue2/3插槽——vue3的jsx组件插槽slot怎么处理

                                                                                                                                                                                                                                                                                                                                                    插槽的作用 让用户可以拓展组件,去更好地复用组件和对其做定制化处理. Vue 实现了一套内容分发的 API,将<slot>元素作为承载分发内容的出口,这是vue文档上的说明.具体来说,sl ...

                                                                                                                                                                                                                                                                                                                                                  9. ios安全加固 ios 加固方案

                                                                                                                                                                                                                                                                                                                                                    ​ 目录 一.iOS加固保护原理 1.字符串混淆 2.类名.方法名混淆 3.程序结构混淆加密 4.反调试.反注入等一些主动保护策略 二 代码混淆步骤 1. 选择要混淆保护的ipa文件 2. 选择要混淆 ...

                                                                                                                                                                                                                                                                                                                                                  10. Gartner 权威预测未来4年网络安全的8大发展趋势

                                                                                                                                                                                                                                                                                                                                                    翻译:SEAL安全 原文标题: Gartner Unveils the Top Eight Cybersecurity Predictions for 2022-23 原文链接: https://ww ...