1. 程式人生 > >利用DBCC PAGE檢視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之間沒有雙向連結串列