通過DBCC IND分析表組織和索引組織


0.參考文獻:

Sql Server中的表組織和索引組織(聚集索引結構,非聚集索引結構,堆結構)

利用DBCC PAGE查看SQL Server中的表和索引數據

1.DBCC IND跟DBCC PAGE簡介

1.1.DBCC IND命令

DBCC IND ( { 'dbname' | dbid }, { 'objname' | objid },
      { nonclustered indid | 1 | 0 | -1 | -2 } [, partition_number]  )

1.2.DBCC輸出字段描述

Column(列) Meaning(含義)
PageFID 索引所在文件ID
PagePID 索引頁ID
IAMFID File ID of the IAM managing this page,IAM page的IAMFID=NULL
IAMPID Page ID of the IAM managing this page,IAM page的IAMPID=NULL
ObjectID 對象ID
IndexID 索引類型ID,0表示堆,1表示聚集索引,2-250表示非聚集索引。可以在sys.indexs上查找
PartitionNumber Partition number within the table or index for this page
PartitionID ID for the partition containing this page (unique in the database)
iam_chain_type Type of allocation unit this page belongs to: in-row data, row-overflow data, or LOB data
PageType Page type: 1 = data page, 2 = index page, 3 = LOB_MIXED_PAGE, 4 = LOB_TREE_PAGE, 10 = IAM page
IndexLevel 索引級別,0表示葉子節點,根節點的級別最高
NextPageFID File ID for next page at this level,同一等級上下一個索引頁所在文件的ID
NextPagePID Page ID for next page at this level
PrevPageFID File ID for previous page at this level
PrevPagePID Page ID for previous page at this level,同一等級上的上一個索引頁,通過雙向鏈表連接起來

1.3.DBCC PAGE

DBCC PAGE 參數DBCC PAGE
(
['database name'|database id], -- can be the actual name or id of the database
file number, -- the file number where the page is found
page number, -- the page number within the file
print option = [0|1|2|3] -- display option; each option provides differing levels of information
)

2.描述索引結構

在<inside sql server 2005:storage engine>的第七章的The Structure of Index Pages小結中提到了索引頁的結構。本文將通過實驗來描述索引頁的結構,然后通過索引頁的結構來更加深刻清晰得描述聚集索引、非聚集索引和多結構。

-----實驗:查看索引頁,推到聚集索引非聚集索引結構------------------------------------------------
use TESTDB3
--1.創建表,有主鍵,sql server默認設置為聚集索引
CREATE TABLE Suppliers
(
  supplierid   INT          NOT NULL IDENTITY,
  companyname  NVARCHAR(40) NOT NULL,
  CONSTRAINT PK_Suppliers PRIMARY KEY(supplierid)
);

 --2.查看頁信息,結果為null,這是因為還沒有數據.索引會根據數據的更新來更新.
dbcc ind ( TESTDB3, [dbo.Suppliers], -1)

--3.插入一條記錄
insert into Suppliers values('zhangsan');

--4.查看頁信息,結果不為null,有兩條記錄。發現IndexID=1表示聚集索引。
dbcc ind ( TESTDB3, [dbo.Suppliers], -1)

--5.創建非聚集索引
CREATE NONCLUSTERED INDEX idx_nc_companyname ON dbo.Suppliers(companyname);

--6.查看頁面信息,發現多了兩條indexID=2的記錄,表示非聚集索引,如果繼續創建非聚集索引,那么IndexID會繼續增加,最大為250.
dbcc ind ( TESTDB3, [dbo.Suppliers], -1)

--7.插入一條記錄
insert into Suppliers values('zhangsan');

--8.查看page信息發現沒變,這是因為一個索引頁可以存放多個索引行,一個數據頁可以存放很多數據行。
dbcc ind ( TESTDB3, [dbo.Suppliers], -1)

--9.插入1000條記錄,超過一個索引頁跟數據頁的容量。
SET NOCOUNT ON--不統計影響行數
declare @i int
set @i=1
while @i<=1000
begin 
    insert into Suppliers values('zhangsan');
    set @i=@i+1
end

--10.再次索引頁信息
dbcc ind ( TESTDB3, [dbo.Suppliers], -1)

上述第10步的查詢結果如下:

上圖包含了非常豐富的信息。

數據頁與索引頁的大小

我們首先來看聚集索引的7個page。其中有5個是PageType=1的,也就是說有5個data page(data page是一種特殊的index page),而剩余2個IAM page和6個index page。

--ps:2012-7-18----------------------------

“Index pages fall into three basic types: leaf level for nonclustered indexes, node (nonleaf) level for clustered indexes, and node level for nonclustered indexes. There isn't really a separate structure for leaf level pages of a clustered index because those are the data pages, which we've already seen in detail. There is, however, one special case for leaf-level clustered index pages which I'll tell you about now.”——from《inside sql server 2005,The Structure of Index Pages》

正如上面因為文獻中提到的,index page 有三種類型:

  1. 非聚集索引的葉子節點
  2. 聚集索引的非葉子節點
  3. 非聚集索引的非葉子節點

而聚集索引的葉子節點是data page。雖然我們可以使用dbcc ind找出data page,但是我們不能講data page看做是index page。

--------------------------------------

我們執行如下命令

--查看表Suppliers的大小
sp_spaceused Suppliers

查詢結果如下圖所示:

我們發現data=40KB,剛好是5個data page的大小,而index_size=64KB,剛好是2個IAM page加上6個index page的大小。

聚集索引與非聚集索引的結構

聚集索引

首先我們查看聚集索引的結構。上圖提供了豐富的信息,我們可以

  • 然后利用利用NextPagePID跟PrevPagePID,我們可以畫出index page的雙向鏈表
  • 利用Index Level我們可以畫出索引層級
  • 利用PageType我們可以找出數據頁和索引頁.

例如,從上圖中我們可以發現,PagePID=2190的這個index page,他的PageType=2,index level=1,表示他是一個索引等級為1的索引頁,不是葉子節點。而PageID=(2184,2191,2194,2196,2198)的這5個index page,他們的PageType=1,index level=0,表明這是5個葉子節點,並且都是data page。因此聚集索引結構如下圖所示。

非聚集索引

利用同樣方法,首先找出非聚集索引的根節點,然后找出葉子節點,葉子節點上有雙向鏈表,如下圖示所示:

我們發現非聚集索引的所有索引節點都是index page,而沒有data page。通過上面的實例,我們再回過頭去看之前寫過的Sql Server中的表組織和索引組織(聚集索引結構,非聚集索引結構,堆結構)這篇文章,會有更深刻的體會。

我們可以通過dbcc page 更加直觀地顯示上述聚集索引和非聚集索引的結構,執行下面的命令

DBCC TRACEON (3604);
GO
DBCC PAGE (TESTDB3,1,2190, 3);--也可以是DBCC PAGE (TESTDB3,1,2190, 1);
DBCC PAGE (TESTDB3,1,2192, 3);--也可以是DBCC PAGE (TESTDB3,1,2190, 1);

查詢結果如下所示:

總結上圖:

  1. 對聚集索引的非葉子節點使用dbcc page,可以求出它的ChildPage。
  2. 對非聚集索引的非葉子節點使用dbcc page,也可以求出它的ChildPage,而且我們可以看到非聚集索引的鍵值。
  3. 如果對聚集索引的葉子節點使用dbcc page,我們可到data page上存儲的數據的二進制代碼。

3.描述堆結構

運行如下實驗

---描述堆結構------------------------
--1.創建堆heap
CREATE TABLE Student
(
  stuid    INT          NOT NULL,
  stuname  NVARCHAR(40) NOT NULL,
);

--2.插入一條記錄
insert into Student values(1,'zhangsan');

--3.查看索引頁信息,發現IndexID=0,表示這是堆結構heap
dbcc ind ( TESTDB3, [Student], -1)

--4.插入1000條記錄,超過一個索引頁跟數據頁的容量。
SET NOCOUNT ON--不統計影響行數
declare @i int
set @i=1
while @i<=1000
begin 
    insert into Student values(1,'zhangsan');
    set @i=@i+1
end

--5.查詢索引頁信息發現只有兩種類型的索引頁,一種IAM page,還有一個是data page.
dbcc ind ( TESTDB3, [Student], -1)

查詢結果如下圖所示:

總結:

  1. 堆結構中只有data page跟IAM page,沒有索引頁。
  2. 堆中的data page沒有層次結構,都是葉子節點
  3. data page之間沒有雙向鏈表

疑問?

聚集索引和非聚集索引中的IAM Page,也就是PageType=10的page是干嘛用的。此問題可以參考博客:SQL Server中Index Allocation Map介紹

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM