博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
pageinspect分析btree索引结构
阅读量:6588 次
发布时间:2019-06-24

本文共 2396 字,大约阅读时间需要 7 分钟。

pg的btree索引有4中类型的索引页面:1、meta page,每个索引都会有该页面,这个页面直接指向root page。2、root page页面,如果heap item很多,会指向新的branch page或者是leaf page。3、branch page页面指向branch page或者leaf page。4、leaf page。

我在9.4.7的版本上8kblock的int类型字段上的索引,大概一个页面可以存407条记录,也就是说,如果你是int索引且只有一个字段记录数在0-407范围内是只有root page的这是1级结构,2级结构的记录数就是407*407,3级结构就是407^3,以此类推。
现在具体开始使用pageinspect分析pg索引结构。先安装pageinspect
image
创建好测试表,插入测试数据。
image
下面开始分析1级结构。找到表a的索引名称
image
使用bt_metap看索引页面信息。
image
这个信息意思就是a_pkey这个索引level=0就说明只有meta page和root page,root page的id是1。
使用bt_page_stats看下索引页面的状态信息。
image
btpo_flags=2表示root节点,btpo_flags=1表示 leaf节点,btpo_flags=0表示 branch节点,btpo_flags=3表示即使root节点又是leaf节点。btpo=0是最底层,btpo_prev和btpo_next表示左右节点页面号。
使用bt_page_items看下索引页面内容。
image
这里面有个注意点,如果该节点是最右节点就是第一条记录就是指向页面的第一条记录,如果不是最右节点就是第二条为第一条记录,第一条记录为右节点的起始item。从bt_page_stats可以看出它的左右节点都是0号页面也就是meta page所以1号页面是最右节点,所以取第一条记录,ctid(0,1)
image

二级结构。

image
level=1代表2级结构,就是meta page,root page,leaf page。root页面id=3。
bt_page_stats信息
image
btpo_flags=2表示这是root节点,btpo=1表示不是最底层,左右节点都是0号页面。
bt_page_items信息
image
因为这个是最右节点所以是第一条记录指向下一个节点页面号。所以是(1,1)
看下1号页面的bt_page_stats信息
image
btpo_flags=1是leaf page,btpo=0是最底层。左节点页面号是0,右节点页面号是2。该节点不是最右节点。
看下1号页面bt_page_items信息
image
因为不是最右节点,所以取第二条记录(0,1)。
看下(0,1)的具体内容。
image

三级结构。

image
level=2说明有meta page,root page,一个branch page,一个leaf page,root page页面号是412。
bt_page_stats信息
image
btpo_flags=2是root节点,btpo=2不是最底层。
bt_page_items信息
image
branch节点页面号是3。

branch节点bt_page_stats。

image
btpo_flags=0,是branch节点,btpo=1不是底层节点。
branch节点bt_page_items。
image
下一叶子节点页面号是(1,1)。

leaf节点bt_page_stats。

image
btpo=0,是底层节点。btpo_flags=1是leaf page。
leaf节点bt_page_items。
image
第一条数据是(0,1)。
image

下面模拟一种异常状况进行分析。

先创建表create unlogged table test03 (id int primary key, info text);
vi test.sql
setrandom id 1 100
insert into test03 values(:id, repeat(md5(random()::text), 1000)) on conflict on constraint test03_pkey do update set info=excluded.info;

第一个会话开启长事务。

第二个会话运行:pgbench -M prepared -n -r -P 1 -f test.sql -c 48 -j 48 -T 2000

正常状态时:

image
长时间运行第二个会话,关闭索引扫描出现的情况:
image
发现大部分都是heap块。看到这里知道了,这个其实是pg的hot update搞得鬼。
hot update 就是更新非索引字段时,会产生一个tuple2,索引指向ctid1,ctid1还是先指向原来的tuple1,再由tuple1指向ctid2,再由ctid2指向tuple2。如果你进行vacuum之后,就是索引指向ctid1,tuple1被回收,ctid1指向ctid2,ctid2指向tuple2。
现在用pageinspect看下这个表的索引情况:
image
这是有meta page,root page,branch page,leaf page这种结构的,root号是412。
image
image

从这两张图可以得出(1,1)到(99,1)除了(99,1)的第一条数据都是id=1的数据。下面看下一共有多少个。

image
是394个。
image
又重新查了下发现(99,1)这个里面就没有id=1的数据。一共扫描的块数就是394+root page+leaf page=396,刚好和上面的计划中扫描块的总数相同。(这里有点小疑问,我觉得应该是计划的是对的,一共是有394条数据但是只需要扫描393个块,索引是扫描了3个,扫描了root leaf1 和leaf99,好像证明不了,按照计划来推断应该是这样算的)。

转载地址:http://rreno.baihongyu.com/

你可能感兴趣的文章
12c rac 实例无法启动之磁盘组空间耗尽
查看>>
keepalived双机热备原理及实例部署LVS+keepalived
查看>>
曲线学习PyQt5方案一
查看>>
爬虫采集-基于webkit核心的客户端Ghost.py [爬虫实例]
查看>>
企业私有云之rabbitmq高可用
查看>>
OpenCV学习】矩阵运算和操作2
查看>>
nginx+ffmpeg搭建rtmp转播rtsp流的flash服务器
查看>>
Win10 IoT C#开发 1 - Raspberry安装IoT系统及搭建开发环境
查看>>
关于在arm裸板编程时使用printf问题的解决方法
查看>>
开源人工智能技术将改变一切
查看>>
2015 上半年 JavaScript 使用统计数据
查看>>
《OpenGL ES 3.x游戏开发(上卷)》一2.4 文件I/O
查看>>
《写给程序员的数据挖掘实践指南》——5.2. 10折交叉验证的例子
查看>>
JVM性能优化, Part 5:Java的伸缩性
查看>>
《Python算法教程》——1.6 如果您感兴趣
查看>>
《正则表达式经典实例(第2版)》——2.18 向正则表达式中添加注释
查看>>
lolcat :一个在 Linux 终端中输出彩虹特效的命令行工具
查看>>
ROS机器人程序设计(原书第2版)3.9 3D可视化
查看>>
干货 | 豆子科技首席架构师钟声:Java的纯真年代
查看>>
《数字图像处理与机器视觉——Visual C++与Matlab实现》——0.2 数字图像处理与识别...
查看>>