我试图了解 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
要检查我的表格的页面:
DBCC IND ( 0, 'mytest', 1);
+---------+---------+--------+--------+------------+---------+-----------------+-------------------+----------------+----------+------------+
| 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 |
+---------+---------+--------+--------+------------+---------+-----------------+-------------------+----------------+----------+------------+
查看数据页的页面详细信息:
dbcc traceon( 3604 )
go
DBCC page( 0, 1, 3519, 1 ) with tableresults
抵消:
Slot 0, Offset 0x60, Length 3016, DumpStyle BYTE
Slot 1, Offset 0xc28, Length 1016, DumpStyle BYTE
Slot 2, Offset 0x1020, Length 3016, DumpStyle BYTE
更新其中一条记录,使其不适合当前页面,并且会发生页面拆分(即)将创建新页面?
update mytest
set filler = replicate( 'B', 3000 )
where something_to_see_in_data = '00002'
现在再次检查页面:
DBCC IND ( 0, 'mytest', 1);
+---------+---------+--------+--------+------------+---------+-----------------+-------------------+----------------+----------+------------+
| 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 |
| 1 | 3521 | 1 | 3520 | 2065259704 | 1 | 1 | 72057595357560832 | In-row data | 2 | 1 |
| 1 | 3522 | 1 | 3520 | 2065259704 | 1 | 1 | 72057595357560832 | In-row data | 1 | 0 |
+---------+---------+--------+--------+------------+---------+-----------------+-------------------+----------------+----------+------------+
正如我们所见,创建了两个新页面:
3521 -- Index page
3522 -- Data page
我可以理解创建新页面的原因,Data page(3522)
因为我的数据超过 8kb,因此创建了新页面。
索引页有什么用,什么时候创建?我在谷歌上做了很多研究,索引页面上没有合适的文档。是为了维护B-Tree吗?
索引页(类型 2)包含聚集索引 b 树的非叶级别。聚集索引的叶级只是底层对象的数据页本身。
在整个对象(在您的情况下为表)适合单个页面的特殊情况下,SQL Server 不会创建单独的索引页面,因为没有必要。
在您的示例中,当页面拆分导致表第一次包含多个数据页时,将创建第一个索引页。
索引页也用于所有级别的非聚集 B 树索引。
索引页也可以用
DBCC PAGE
. 转储样式 3 提供的信息最多,因为它显示了索引键范围的子文件和页面指针。这是向下导航(可能是多个级别)b 树索引所需的信息。随着索引中行数的增加,索引中的级别数也会增加。
看:
有关表和索引内部结构的综合信息可以在 Kalen Delaney 等人的 Microsoft SQL Server Internals 书籍中找到。
每当现有索引页需要拆分时,都会创建一个新的索引页。如果该页面是根页面(索引树的顶部),索引将因此获得一个新的级别。如果索引键被加宽,或者如果该页面上需要另一个条目(例如,引用一个新的子页面)并且没有足够的空间,则索引页面可以拆分。