通过 pageinspect 和 pgstattuple 两个内置扩展,可以直接观察 B-tree 索引从单页生长到多层树的完整过程,并量化每次页面分裂带来的 WAL 生成和缓冲区访问开销。
实验用 EXPLAIN (analyze, buffers, wal) 配合两个扩展,逐行插入随机 UUID 并收集统计信息。关键发现:
• 前 291 行全部写入单个页面(根页即叶页),每次插入仅 2 条 WAL 记录、2 个共享缓冲区。
• 第 292 行触发首次分裂:生成新根页,树升到 1 层,WAL 变为 3 条、缓冲区 3 个。
• 后续叶页分裂使 WAL 增加到 3 条,分支页分裂则达 4 条,缓冲区也相应增加(层数越多缓冲越多)。
• 当根页下指 291 个叶页时根页满,树升至 2 层(第 61346 行),此时插入需 4 条 WAL、4 个缓冲区。
• 继续增长直到索引超过 417 MB、53193 个叶页时,根页再次分裂,树升到 3 层。
即使大型索引深度通常也只有 2–3 层,内部页面数量少、易缓存,查询 I/O 瓶颈更多在堆页面而非 B-tree 遍历。
GitHub
#开发者 #工具 #PostgreSQL #Btree #页面分裂 #WAL #pageinspect #pgstattuple #FranckPachot
@DevToolboxHub