天天看點

IAM頁,IAM連結清單,配置設定單元

目錄

<a href="#_Toc332562539">IAM頁... 1</a>

<a href="#_Toc332562540">IAM連結清單... 3</a>

<a href="#_Toc332562541">配置設定單元... 4</a>

<a href="#_Toc332562542">包含列... 4</a>

<a href="#_Toc332562543">寬行(Large Rows)... 5</a>

<a href="#_Toc332562544">分區... 5</a>

一個IAM(index allocation map)頁跟蹤單個檔案中近4GB空間,和4GB的空間對齊。這些4GB的塊被叫做’GAM intervals’。一個IAM頁跟蹤的空間屬于一個對象。

一個IAM頁隻能跟蹤一個檔案中的一個GAM interval,是以如果資料庫有多個檔案,或者有些檔案大于4gb,那麼一個執行個體被配置設定到多個檔案或者一個檔案中有多個GAM intervals,之後你就會發現每個對象需要的IAM頁數量,來跟蹤使用的空間。如果對象請求多個IAM頁跟蹤所有的擴充,那麼這些IAM頁就會被串起來。這個就是IAM連結清單。

每個IAM頁有2個記錄,一個是IAM頭,一個是IAM位圖。讓我們看看DBCC PAGE。我們使用頁拆分來看。運作dbcc ind 傳回以下結果:

IAM頁,IAM連結清單,配置設定單元

DBCC TRACEON (3604);

GO

DBCC PAGE ('pagesplittest', 1, 152, 3);

m_pageId = (1:152)                   m_headerVersion = 1                  m_type = 10

m_typeFlagBits =

0x0                

m_level =

m_flagBits = 0x200

m_objId (AllocUnitId.idObj) = 68     m_indexId

(AllocUnitId.idInd) = 256

Metadata: AllocUnitId = 72057594042384384

Metadata: PartitionId =

72057594038386688                                

Metadata: IndexId = 1

Metadata: ObjectId = 2073058421      m_prevPage =

(0:0)                  

m_nextPage = (0:0)

pminlen =

90                        

m_slotCnt =

2                       

m_freeCnt = 6

m_freeData =

8182                   

m_reservedCnt =

m_lsn = (18:116:13)

m_xactReserved =

m_xdesId =

(0:0)                    

m_ghostRecCnt = 0

m_tornBits = -1947725876

Allocation Status

GAM (1:2) =

ALLOCATED               

SGAM (1:3) = ALLOCATED

PFS (1:1) = 0x70 IAM_PG MIXED_EXT ALLOCATED  

0_PCT_FULL                 

DIFF (1:6) = CHANGED

ML (1:7) = NOT MIN_LOGGED

IAM: Header @0x620CC064 Slot 0, Offset 96

sequenceNumber =

status =

0x0                        

objectId = 0

indexId =

page_count =

start_pg = (1:0)

IAM: Single Page Allocations @0x620CC08E

Slot 0 =

(1:143)                    

Slot 1 =

(1:153)                    

Slot 2 = (1:154)

Slot 3 =

(0:0)                      

Slot 4 =

Slot 5 = (0:0)

Slot 6 =

Slot 7 = (0:0)

IAM: Extent Alloc Status Slot 1 @0x620CC0C2

(1:0)       

- (1:272)      = NOT ALLOCATED

在頁頭上有些東西我們需要注意:

l  頁類型為10

l  前一頁,後一頁為null,因為這個iam連結清單中沒有其他的iam頁

l  Slot的個數是2,一個是iam頭記錄,一個是bitmap記錄

l  頁幾乎是空的

IAM頁頭有一下元素:

Sequencenumber

         IAM頁在IAM連結清單中的位置。IAM連結清單增加IAM頁的時候會遞增。

Status

         已經不使用

Objected

Indexed

         在SQL Server

2000或者以前,表示所屬的是以。在SQL Server 2005之後就未使用。

Page_count

         未使用,以前被用來記錄單頁配置設定的頁數。

Start_pg

         儲存了GAM

interval的第一個page id。

Single Page Alloctions array

         這些頁是從混合擴充中配置設定的,這個隊列隻用在隊列中的第一個IAM。

Bitmap中每個GAM Interval 中的擴充占一個bit。當擴充被配置設定的時候bit被設定,如果沒有就會被清除。在一個GAM interval中有兩個IAM頁對應不同的對象,怎麼這2個不能有相同的bit設定-可是使用 dbcc checkdb檢查。Dbcc page 你會發現沒有擴充配置設定。你會發現輸出直到以272頁開始的擴充-這個是因為資料檔案隻有這麼大。插入更多的列,在做dbcc page。下面是輸出:

Slot 0 = (1:143)                    

(1:155)                    

(1:156)                    

Slot 5 = (1:157)

(1:158)                    

Slot 7 = (1:159)

IAM: Extent Alloc

Status Slot 1 @0x620CC0C2

- (1:152)      = NOT ALLOCATED

(1:160)      - (1:296)     

=     ALLOCATED

(1:304)      - (1:400)      =

NOT ALLOCATED

你會看到單頁配置設定隊列滿了,之後配置設定切換到專用擴充。第一個可用的擴充從160頁開始并且所有的擴充到296開始的擴充結束是已經被配置設定的。注意檔案肯定增長,因為輸出中增長到了400頁。

IAM需要注意的資訊:

         自身的從混合擴充中配置設定的單頁不會再任何地方跟蹤。

         他們可以從其他檔案上被配置設定來跟蹤任何位置的擴充。

如果我們繼續增長檔案填充表,之後我們需要另外一個IAM頁來映射另外一個GAM interval。就形成了一個IAM連結清單。這個清單的IAM頁配置設定到一個對象。連結清單并沒有排序-IAM頁被加入隻是因為空間的需要。IAM頁被編号,當被添加到清單的時候編号順序排序。

不同的對象是否使用同一個IAM連結清單?在sql server 2000 和sql server 2005 中答案是不一樣的。

在sql server 2000 中,以下狀況都會有一個IAM連結清單:

         堆或者聚集索引

                   一個表隻能有一個堆或者聚集索引。Index id的編号是分别是 0 和1。

         非聚集索引

                   Index

id 為2到250(也就是你隻能有249個索引)

         表完整的LOB存儲

                   對于LOB列。的索引為全文索引,indexid為255

Sql server 2000 中每個對象有251個iam連結清單。我通常會說在sql

server 2000中一個索引隻有一個IAM連結清單。

在sql server 2005 或者之後的版本,很多東西都被修改。IAM連結清單和IAM頁幾乎相同,但是2者是不同的。一個表可以有750000個IAM連結清單一下是新的3個事情配置設定IAM連結清單:

1.    堆或者b樹(b樹是index存儲的内部結構)

2.    LOB 資料

3.    行溢出資料

我們叫這些空間配置設定單元叫配置設定單元。3個配置設定單元内部的名字:

1.      

hobt配置設定單元(堆或b樹,簡稱hobbit)。

2.      

LOB配置設定單元

3.      

SLOB配置設定單元(小LOB或者斷LOB)

外部名稱叫做:

IN_ROW_DATA配置設定單元

LOB_DATA 配置設定單元

ROW_OVERFLOW_DATA 配置設定單元

他們不是真正的IAM連結清單,因為不在跟蹤一個索引的空間配置設定,他們的IAM頁連結清單還是叫做IAM連結清單,單元的跟蹤現在被叫做配置設定單元。區分他們,其實沒什麼不同點。

讓我們快速的浏覽sql server 2005中這3個新的特性的必要性和如何提升一個表的IAM連結清單數量。

非聚集索引可以把非key列加入到索引的葉子節點中。這個很有用:

允許非聚集索引真正的覆寫查詢,當查詢結果多餘16個列的時候或者查詢的結果大于900個位元組的時候(記住非聚集索引的key列被限制為16個列,900個位元組)。

允許被包含的列不是索引鍵的一部分(如 varchar(max)或者XML)。

允許非聚集索引覆寫不需要所有的列都在key中。因為key 會被包含在索引的各個非葉子節點上,這樣做可以減少索引的大小

一個空間縮小的例子:想象一個1000萬行的行索引,鍵的長度為900位元組,但是隻有前面2個整型的鍵值被真正的使用,其他4個固定長度的列可以被儲存在包含列中。900個位元組8行可以填滿一個資料頁。也就意味着需要12500000個葉子節點,1562500倒數第二層節點等待,一共需要12500000 + 1562500 + 195313 + 24415 + 3052 + 382 + 48 + 6 + 1 = 14285717個頁(包含1785717來存儲非葉子節點)。

如果我們使用包含列key大小被縮小為8個位元組,加上行頭非葉子節點的行大小下降到15個位元組。注意行上面的扇出還是8,因為所有的include存儲在葉子節點上。是以有12500000個葉子節點,23278個上級節點,一共有12500000 + 23278 + 44 + 1 = 12523323個頁(有23323個非葉子節點)。比較900個位元組的key,減小了12%或者13.6GB。

真正增加這個特性的理由是索引覆寫,優化器知道一個覆寫索引可以從索引中擷取所有的查詢結果,是以查詢可以不發生額外的io,提高性能。

非聚集索引可以包含LOB列(在2005 中隻能包含varchar(max),nvarchar(max),varbinary(max),和XML)。這就索引單個LOB配置設定單元不可能更多因為每個索引可以有自己的LOB。

是以一個索引需要2個配置設定單元一個是行内資料一個是LOB資料。

對于表設計者來說行限制大小為8060個位元組是個災難在sql server 2005這個限制就被取消了。方法是使用可變化長度列(varchar,sqlvariant)超過一行最大一頁的限制。

但是實際上超出了嗎?這些列是有效的小lob資料列。這些資料被24個位元組(可能是36,48,或者72個位元組替換)的指針指向超出的的資料,就像lob一樣被存儲在一個獨立的配置設定單元中-行溢出(或者SLOB)配置設定單元。這些值和LOB值一樣被存儲在文本頁上的原理是一樣的,隻是使用了獨立的配置設定單元。當第一個列值溢出的時候SLOB配置設定單元才會被建立。

這個特性在非聚集索引中也适用,考慮如果你把包含列加入到索引中,可能超出了一個頁。使用900位元組的限制被替換為8060位元組的限制,沒有使用擴充行溢出屬性會太過短淺。

現在使用新特性,每個索引可以有3個配置設定單元,hobt,LOB,和SLOB。如果單單隻有這些那麼一個表的擴充單元最多可以有750個(一個IAM連結清單為一個配置設定單元,映射一個存儲配置設定是以250個索引*3配置設定單元= 750個IAM連結清單)。這裡隻有750個連結清單那麼其他的從哪裡來呢?

一個表可以有1000個分區。分區是sql server 2005的新特性允許表,索引線性的劃分為幾段,每段都是獨立存儲(和獨立的檔案組類似)。分區是是獨立基礎。

每個表的分區或者表的分區是獨立存儲的,每個都需要自己的hobt配置設定單元。當然,每個分區的LOB值也需要存儲。行溢出特性也是每行的,是以每個分區的行會溢出到SLOB配置設定單元和未分區的表和索引一樣。表和索引的每個分區可以有3個配置設定單元(也就是3個IAM連結清單)。

這就是1000的來曆,每個表或者索引可以有1000個分區。250個索引*1000分區*3個配置設定單元 = 750000IAM連結清單。當然這個事情是不會發生的,但是是有可能的。