2017-03-16 114 views
0

我想了解PostgreSQL物理索引布局是如何的。我所知道的是索引是作为B树数据结构的一组页面的一部分存储的。我想了解如何真空影响指数。它有助于控制它的大小吗?PostgreSQL索引物理布局

回答

2

B-tree索引是十年前的技术,所以网络搜索会带来很多很好的详细描述。简而言之:

B树是平衡树索引页(在PostgreSQL的8KB),也就是树的每个分支都有相同的深度。 树通常是上下颠倒的,起始(顶部)节点是根节点,底部的页面被称为叶节点。 树的每个级别分割搜索空间;级别越深,分区越精细,直到在叶节点中达到各个索引条目。 索引页中的每个条目都指向一个表条目(在叶节点中)或下一级别的另一个索引页。

这是深中三指数的草图,但记住以下几点:

  • 一些节点被省略,在现实中所有叶子节点都在3
  • 水平实际上这里不三个条目()中的一个节点,但大约100

 

         ┌───────────┐ 
       level 1 (root node) │ 20 75 100 │ 
            └───────────┘ 
            ╱ ╱ │  ╲ 
            ╱ ╱ │  ╲ 
           ╱ ╱  │  ╲ 
        ┌───────────┐┌─────┐┌──────────┐┌─────┐ 
      level 2 │ 5 10 15 ││ ... ││ 80 87 95 ││ ... │ 
        └───────────┘└─────┘└──────────┘└─────┘ 
             ╱ ╱ │ ╲ 
             ╱ ╱ │  ╲ 
            ╱ ╱  │  ╲ 
          ┌─────┐┌─────┐┌──────────┐┌─────┐ 
     level 3 (leaf nodes) │ ... ││ ... ││ 89 91 92 ││ ... │ 
          └─────┘└─────┘└──────────┘└─────┘ 

一些注意事项:

  • 指针到一个新的水平实际上是在项目之间的差距,在索引中搜索就像“向下钻取”正确的叶子页。
  • 每个节点ia也与它的同胞连接,以便于插入和删除节点。
  • 当一个节点已满时,它被分成两个新节点。这种分裂可以递增,甚至到达根节点。当根节点被拆分时,索引的深度增加1.
  • 在现实生活中,B树索引的深度几乎不能超过5.
  • 当索引条目被删除时,剩余的空白空间。有些技术可以通过加入页面来加以巩固,但这很棘手,而PostgreSQL不会那样做。

现在你的问题:

当一个表()项由VACUUM删除,因为它不是任何活动快照可见,在指数中的相应条目被移除。这会在索引中产生空的空间,可以被未来的索引条目重复使用。

可以删除空索引页面,但索引的深度永远不会减小。因此,批量删除可以VACUUM已完成其工作后)减少索引大小,但更可能导致臃肿索引页面只包含几个键和大量的空白空间。

一定数量的指数膨胀(高达50%以上)是正常的,但如果像海量更新和删除这样的异常使用模式导致指数膨胀不良,则必须用REINDEX重写指数,从而摆脱的膨胀。不幸的是,这个操作会锁定索引,这样所有的并发访问都会被阻塞,直到完成。