碎片產生
在SQL Server中,存儲數據的最小單位是頁,每一頁所能容納的數據為8060字節.而頁的組織方式是通過B樹結構
SQL Server向每個頁內存儲數據的最小單位是表的行(Row)
當葉子節點中新插入的行或更新的行使得葉子節點無法容納當前更新或者插入的行時,分頁就產生了
在分頁的過程中,就會產生碎片
碎片分類
外部碎片
理解外部碎片的這個“外”是相對頁面來說的,外部碎片指的是由於分頁而產生的碎片
在SQL SERVER中,新的頁是隨着數據的增長不斷產生的,而聚集索引要求行之間連續,所以很多情況下分頁后和原來的頁在磁盤上並不連續
對性能的影響
由於分頁會導致數據在頁之間的移動,所以如果插入更新等操作經常需要導致分頁,則會大大提升IO消耗,造成性能下降
而對於查找來說,在有特定搜索條件,比如where子句有很細的限制或者返回無序結果集時,外部碎片並不會對性能產生影響。但如果要返回掃描聚集索引而查找連續頁面時,外部碎片就會產生性能上的影響
在SQL Server中,比頁更大的單位是區(Extent).一個區可以容納8個頁.區作為磁盤分配的物理單元.所以當頁分割如果跨區后,需要多次切區。需要更多的掃描.因為讀取連續數據時會不能預讀,從而造成額外的物理讀,增加磁盤IO
外部碎片對於性能的影響,主要是在於需要進行更多的跨區掃描,從而造成更多的IO操作
內部碎片
內部碎片的”內”也是相對頁來說的
創建一張表,插入小於8060字節的數據,此時數據在1頁上。之后更新數據,使數據大於8060字節,則需要分頁,在兩個頁上都出現了碎片
對性能的影響
內部碎片會造成數據行分布在更多的頁中,從而加重了掃描的頁樹,也會降低查詢性能
查詢碎片
--選擇好目標數據庫,新建查詢執行下列語句 --顯示數據庫里所有索引的碎片信息 DBCC SHOWCONTIG WITH ALL_INDEXES --顯示指定表的所有索引的碎片信息 DBCC SHOWCONTIG (authors) WITH ALL_INDEXES --顯示指定索引的碎片信息 DBCC SHOWCONTIG (authors,aunmind)
數據解釋
掃描頁數:如果你知道行的近似尺寸和表或索引里的行數,那么你可以估計出索引里的頁數。看看掃描頁數,如果明顯比你估計的頁數要高,說明存在內部碎片
掃描擴展盤區數:用掃描頁數除以8,四舍五入到下一個最高值。該值應該和DBCC SHOWCONTIG返回的掃描擴展盤區數一致。如果DBCC SHOWCONTIG返回的數高,說明存在外部碎片。碎片的嚴重程度依賴於剛才顯示的值比估計值高多少
擴展盤區開關數:該數應該等於掃描擴展盤區數減1。高了則說明有外部碎片
每個擴展盤區上的平均頁數:該數是掃描頁數除以掃描擴展盤區數,一般是8。小於8說明有外部碎片
掃描密度[最佳值:實際值]:DBCC SHOWCONTIG返回最有用的一個百分比。這是擴展盤區的最佳值和實際值的比率。該百分比應該盡可能靠近100%。低了則說明有外部碎片
邏輯掃描碎片:無序頁的百分比。該百分比應該在0%到10%之間,高了則說明有外部碎片
擴展盤區掃描碎片:無序擴展盤區在掃描索引葉級頁中所占的百分比。該百分比應該是0%,高了則說明有外部碎片
每頁上的平均可用字節數:所掃描的頁上的平均可用字節數。越高說明有內部碎片,不過在你用這個數字決定是否有內部碎片之前,應該考慮fill factor(填充因子)
平均頁密度(完整):每頁上的平均可用字節數的百分比的相反數。低的百分比說明有內部碎片
碎片整理
刪除並重建索引
用DROP INDEX和CREATE INDEX或ALTER TABLE來刪除並重建索引有些缺陷包括在刪除重建期間索引會消失。在索引刪除重建時,對於查詢它不再可用,查詢性能也許會受到明顯的影響,直到重建索引為止。另一個潛在的缺陷是當都請求索引的時候會引起阻塞,直到重建索引為止。通過其他的處理也能解決阻塞,就是索引被使用的時候不刪除索引。另一個主要的缺陷是在用DROP INDEX和CREATE INDEX重建聚集索引時會引起非聚集索引重建兩次。刪除聚集索引時非聚集索引的行指針會指向數據堆,聚集索引重建時非聚集索引的行指針又會指回聚集索引的行位置。
刪除並重建索引的確有一個好處就是通過重新排序索引頁,使索引頁緊湊並刪除不需要的索引頁來完全重建索引。你也許需要考慮那些內部和外部碎片都很高的情況下才使用,以使那些索引回到它們應該在的位置。
使用DROP_EXISTING子句重建索引
為了避免在重建聚集索引時表上的非聚集索引重建兩次,可以使用帶DROP_EXISTING子句的CREATE INDEX語句。這個子句會保留聚集索引鍵值,以避免非聚集索引重建兩次。和刪除並重建索引一樣,該方法也可能會引起阻塞和索引消失的問題。該方法的另一個缺陷是也強迫你去分別發現和修復表上的每一個索引。
除了和上一個方法一樣的好處之外,該方法的好處是不必重建非聚集索引兩次。這樣可以對那些帶約束的索引提供正確的索引定義以符合約束的要求。
執行DBCC DBREINDEX
DBCC DBREINDEX類似於第二種方法,但它物理地重建索引,允許SQLServer給索引分配新頁來減少內部和外部碎片。DBCC DBREINDEX也能動態的重建帶約束的索引,不像第二種方法。
DBCC DBREINDEX的缺陷是會遇到或引起阻塞問題。DBCC DBREINDEX是作為一個事務來運行的,所以如果在完成之前中斷了,那么你會丟失所有已經執行過的碎片。
執行DBCC INDEXDEFRAG
DBCC INDEXDEFRAG(在SQLServer2000中可用)按照索引鍵的邏輯順序,通過重新整理索引里存在的葉頁來減少外部碎片,通過壓縮索引頁里的行然后刪除那些由此產生的不需要的頁來減少內部碎片。它不會遇到阻塞問題但它的結果沒有其他幾個方法徹底。這是因為DBCC INDEXDEFRAG跳過了鎖定的頁且不使用任何新頁來重新排序索引。如果索引的碎片數量大的話你也許會發現DBCC INDEXDEFRAG比重建索引花費的時間更長。DBCC INDEXDEFRAG比其他方法的確有好處的是在其他過程訪問索引時也能進行碎片整理,不會引起其他方法的阻塞問題。
參考:
http://blog.sina.com.cn/s/blog_6d2675450101ks6i.html
http://www.jb51.net/softjc/126055.html
