Sql-Server

索引頁面(頁麵類型 2)

  • October 22, 2021

我試圖了解 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,所以創建了新頁面。

索引頁面的用途是什麼,何時創建?我在Google做了很多研究,索引頁面上沒有適當的文件。是為了維護B-Tree嗎?

索引頁(類型 2)保存聚集索引 b 樹的非葉級別。聚集索引的葉級只是底層對象的數據頁本身。

在整個對象(在您的情況下為表)適合單個頁面的特殊情況下,SQL Server 不會創建單獨的索引頁面,因為沒有必要。

在您的範例中,當頁面拆分第一次導致表包含多個數據頁時,將創建第一個索引頁。

索引頁也用於所有級別的非聚集 b 樹索引。

索引頁也可以用DBCC PAGE. 轉儲樣式 3 提供的資訊最多,因為它顯示了索引鍵範圍的子文件和頁面指針。這是向下導航(可能是多個級別)b-tree 索引所需的資訊。

隨著索引中行數的增加,索引中的級別數也會增加。

看:

有關表和索引內部的全面資訊可以在 Kalen Delaney 等人的 Microsoft SQL Server 內部書籍中找到。

每當現有索引頁面需要拆分時,都會創建一個新的索引頁面。如果該頁面是根頁面(索引樹的頂部),則索引會因此獲得新的級別。如果索引鍵被加寬,或者該頁面上需要另一個條目(例如,引用新的子頁面)並且沒有足夠的空間,則索引頁面可以拆分。

引用自:https://dba.stackexchange.com/questions/159239