索引页面(页面类型 2)

Pரத*_*ீப் 6 index sql-server database-internals page-splits

我试图了解 SQL Server 中的页面拆分,阅读什么是页面拆分发生什么了?为什么会这样?为什么要担心?通过托尼·罗杰森

CREATE TABLE mytest
  (
     something_to_see_in_data CHAR(5) NOT NULL CONSTRAINT pk_mytest PRIMARY KEY CLUSTERED,
     filler                   VARCHAR(3000) NOT NULL
  ) 

go

insert mytest ( something_to_see_in_data, filler ) values( '00001', replicate( 'A', 3000 ) )
insert mytest ( something_to_see_in_data, filler ) values( '00002', replicate( 'B', 1000 ) )
insert mytest ( something_to_see_in_data, filler ) values( '00003', replicate( 'C', 3000 ) )
go
Run Code Online (Sandbox Code Playgroud)

要检查我的表的页面:

DBCC IND ( 0, 'mytest', 1);
Run Code Online (Sandbox Code Playgroud)
CREATE TABLE mytest
  (
     something_to_see_in_data CHAR(5) NOT NULL CONSTRAINT pk_mytest PRIMARY KEY CLUSTERED,
     filler                   VARCHAR(3000) NOT NULL
  ) 

go

insert mytest ( something_to_see_in_data, filler ) values( '00001', replicate( 'A', 3000 ) )
insert mytest ( something_to_see_in_data, filler ) values( '00002', replicate( 'B', 1000 ) )
insert mytest ( something_to_see_in_data, filler ) values( '00003', replicate( 'C', 3000 ) )
go
Run Code Online (Sandbox Code Playgroud)

查看数据页面的页面详情:

dbcc traceon( 3604 )  

go 

DBCC page( 0, 1, 3519, 1 ) with tableresults 
Run Code Online (Sandbox Code Playgroud)

抵消:

DBCC IND ( 0, 'mytest', 1);
Run Code Online (Sandbox Code Playgroud)

更新其中一条记录,使其不适合当前页面,并且会发生页面拆分(即)将创建新页面?

update mytest
    set filler = replicate( 'B', 3000 )
where something_to_see_in_data = '00002'
Run Code Online (Sandbox Code Playgroud)

现在再次检查页面:

DBCC IND ( 0, 'mytest', 1);
Run Code Online (Sandbox Code Playgroud)
+---------+---------+--------+--------+------------+---------+-----------------+-------------------+----------------+----------+------------+
| PageFID | PagePID | IAMFID | IAMPID |  ObjectID  | IndexID | PartitionNumber |    PartitionID    | iam_chain_type | PageType | IndexLevel |
+---------+---------+--------+--------+------------+---------+-----------------+-------------------+----------------+----------+------------+
|       1 |    3520 | NULL   | NULL   | 2065259704 |       1 |               1 | 72057595357560832 | In-row data    |       10 | NULL       |
|       1 |    3519 | 1      | 3520   | 2065259704 |       1 |               1 | 72057595357560832 | In-row data    |        1 | 0          |
+---------+---------+--------+--------+------------+---------+-----------------+-------------------+----------------+----------+------------+
Run Code Online (Sandbox Code Playgroud)

如我们所见,创建了两个新页面:

dbcc traceon( 3604 )  

go 

DBCC page( 0, 1, 3519, 1 ) with tableresults 
Run Code Online (Sandbox Code Playgroud)

我可以理解创建 new 背后的原因,Data page(3522)因为我的数据超过 8kb,所以创建了新页面。

索引页有什么用,什么时候创建?我在谷歌做了很多研究,索引页面上没有适当的文档。是为了维护B-Tree吗?

Pau*_*ite 14

索引页(类型 2)保存聚集索引 b 树的非叶级别。聚集索引的叶级只是底层对象的数据页本身。

在整个对象(您的案例中的表)适合单个页面的特殊情况下,SQL Server 不会创建单独的索引页,因为没有必要。

在您的示例中,当页面拆分第一次导致表包含多个数据页时,将创建第一个索引页。

索引页也用于所有级别的非聚集 b 树索引。

也可以使用 来检查索引页DBCC PAGE。转储样式 3 的信息量最大,因为它显示了索引键范围的子文件和页面指针。这是向下导航(可能是多个级别)b 树索引所需的信息。

随着索引中行数的增加,索引中的级别数也会增加。

看:

有关表和索引内部结构的综合信息可以在 Kalen Delaney 等人的 Microsoft SQL Server Internals 书籍中找到。

每当现有索引页需要拆分时,都会创建一个新的索引页。如果该页面是根页面(索引树的顶部),则索引会因此获得一个新级别。如果索引键被加宽,或者如果该页面上需要另一个条目(例如引用新的子页面)并且没有足够的空间,则索引页面可以拆分。