問題描述
建立乙個新錶時,乙個非常重要的設計原則就是建立還是不建立聚集索引的決定。沒有聚集索引的表被稱為堆,擁有聚集索引的表叫聚集索引表。 聚集索引錶比堆表擁有一些好處(優勢),比如聚集索引表是基於聚集索引鍵順序儲存的,正因為如此,所以通過聚集索引可以快速查詢某一行;可以通過重建聚集 索引重新組織資料。當你對錶進行insert、update、delete等操作時可能會使物理資料變得碎片化,這種碎片化可能會導致你浪費大量資料庫存 儲空間,因為本來可以儲存在一頁的資料,需要儲存在多個資料頁上(pages),那麼,我們該怎麼做呢?
解決方案
我們要解決的首要問題是發生在資料庫正常活動中的碎片。你的表是否擁有聚集索引 將決定您是否可以在資料庫物理層面很容易的解決碎片化問題。因為堆或聚集索引決定你表資料的物理儲存,每個表要麼擁有乙個聚集索引或沒有乙個聚集索引,所 以每個表要麼是乙個堆或聚集索引表。
讓我們來看看乙個堆表和聚集索引表之間的差異:
heap
資料儲存沒有任何特定的順序。
不能快速的找到特定資料,除非也有非聚集索引。
資料頁之間沒有指標關聯,所以順序訪問需要重新返回到索引分配對映(iam)頁
既然沒有聚集索引,所以不用額外的時間去維護聚集索引。
既然沒有聚集索引,所以不用額外的空間去儲存聚集索引樹。
堆表的索引在sys.indexes目錄檢視的記錄的index_id字段值為0
資料儲存基於聚集索引鍵順序儲存。
如果查詢時使用聚集索引列,資料可以基於聚集索引鍵快速檢索到。
資料頁之間有指標鏈結,可以更快速的順序訪問。
當insert、update、delete操作時,需要額外的時間維護聚集索引。
需要額外的空間儲存聚集索引樹。
聚集索引表在sys.indexes目錄檢視的記錄的index_id值為1.
所以,基於以上你可以看到有乙個表是否具有聚簇索引將決定表的一些根本性的不同之處。
碎片化問題
所有的表都會發生的乙個問題就是碎片化的問題。根據不同的操作,比如刪除,插入和更新,您的堆表和聚集索引表將會變得越來越碎片化。碎片化很多時候取決於insert、update、delte這類操作,以及用作聚集索引的鍵。
如果您的堆表只有insert操作,你的表不會變得碎片化,因為只有新的資料寫入。
如果您的聚集索引鍵是連續的,比如乙個自增字段。並且對該錶你只有insert操作,這同樣也不會變得碎片化,因為新的資料總是寫在聚簇索引的後面。
但是,如果你的表是乙個堆或聚集表,並有大量的插入,更新和刪除操作,資料頁碎片化可能會變得越來越嚴重。這不僅會導致浪費額外的空間,而且需要讀取額外的資料頁來滿足查詢。
當乙個表在堆上建立,sql server不會強迫在那個新資料頁(new page)寫入資料。每當新的資料寫入時,該資料總是寫在表的末端,或者分配給該表中的下乙個可用的頁面上。當資料被刪除時,資料頁上的空間釋放出來,但 它不重複使用,因為新資料總是寫入到下乙個可用的頁面。
具有聚簇索引,根據索引鍵,新的記錄可能會被寫入到現有的頁面,這些頁面可能存在的空閒的空間或者有可能需要分割成多個頁面的頁面。以便插入新的資料。刪 除時會發生同樣的問題時,與乙個堆對比,但是這些空閒間可以再次使用,如果資料需要插入到具有可用空間的現有頁面中的乙個。
所以,基於以上敘述 ,你的堆表可能變得比你的聚集表更加支離破碎。
檢視碎片化
要確定您的聚集索引表或堆表是否碎片化,你要麼通過執行dbcc showcontig
(sql serever 2000或sql serever 2005)檢視,或使用新的dmv
sys.dm_db_index_physical_stats
sql server 2000 to 2005 crosswalk - index rebuilds.
解決碎片化
聚集索引表
sql server 2000 to 2005 crosswalk - index rebuilds
堆表
對於堆表來說,這個不太容易的。您可以採取以下不同的方法來解決碎片問題:
對堆表建立乙個聚集索引
建立乙個新的堆表,並根據某種順序將舊表中的資料插入到新錶
匯出資料,截斷表並匯入資料返回到表
附加資訊
當你通過企業管理器或management studio建立乙個新錶並在新錶中指定乙個主鍵,管理工具會自動為其建立乙個聚集索引,但可以被重寫。當通過指令碼建立乙個新錶時,你需要明確指定建立聚 集索引。所以,正是由於主鍵關係,你大部分的表將會擁有乙個聚集索引,但如果建立表時,你不指定乙個主鍵或建立聚集索引,該錶的資料將被儲存為乙個堆。
下一步
維持表和索引的碎片化在控制範圍內是保持資料庫最佳效能的乙個關鍵過程。現在你可以明白乙個堆與聚集索引表在解決碎片化上的不同,看看你的表結構,看看你需要解決這些問題。
即使對所有表乙個星期做一次索引重建,你的堆表是永遠不會解決瑣碎化問題的,所以你需要想出另一種策略來處理堆表的碎片問題。
sql server 2000 to 2005 crosswalk - database fragmentation.
sql server 2000 to 2005 crosswalk - index rebuilds.
基於上述論證,似乎所有的表都應該有乙個聚集索引。在大多數情況下是這樣,但也可能由於某種原因,你不希望有乙個聚集索引。乙個原因可能是該錶只有insert操作,例如乙個日誌記錄的表。但是毫無疑問,有聚集索引一定好過沒有聚集索引
06 索引 非聚集索引 2 堆表
刪除聚集索引 drop index cix employee001 id onemployee001 索引情況 select database id index id index type desc index depth index level page count from sys.dm db ...
05 索引 非聚集索引 1 聚集表
建立非聚集索引 create nonclustered index ncix employee001 department organization onemployee001 department organization alter index ncix employee001 departme...
mysql堆表和索引組織 堆表與索引組織表
堆表 資料存放在資料裡面,索引存放在索引裡 堆就是無序資料的集合,索引就是將資料變得有序,在索引中鍵值有序,資料還是無序的 堆表中,主鍵索引和普通索引一樣的,葉子節點存放的是指向堆表中資料的指標 可以是乙個頁編號加偏移量 指向實體地址,沒有回表的說法 堆表中,主鍵和普通索引基本上沒區別,和非空的唯一...