[筆記整理]SQL Server 索引碎片 和 重建索引

鋪墊知識點:

數據庫存儲自己是無序的,創建了彙集索引,會按照彙集索引物理順序存入硬盤。既鍵值的邏輯順序決定了表中相應行的物理順序html

多數狀況下,數據庫讀取頻率遠高於寫入頻率,索引的存在 爲了讀取速度犧牲寫入速度數據庫

頁 爲最小單位 8kb併發

區 物理連續的頁(8頁)的集合函數

內部碎片 數據庫頁內部產生的碎片,外部反之post

 

碎片的產生:

有一個表裏有8條數據,已經將一頁填滿,這個時候要插入第九條數據,頁也就分裂了。這就產生了內部碎片。以下圖所示(excel示意一下  懶癌晚期)url

注: 不會將9單獨分到第二頁,索引B+樹存儲,會讓存儲儘可能平衡,以減小檢索層級。spa

   且通常狀況下SQL Server數據庫默認設置有20%的填充因子(可設置),既新建頁80%存數據,20%爲update和insert預留。3d

另外,在插入1~8以後  9以前,極可能數據庫在這段時間有N多新增數據,也就是在物理結構上 頁1 和 頁2 沒法連續。這就沒法避免的產生了外部碎片指針

 

查看碎片狀況:

用到這個極重要的 sys.dm_db_index_physical_stats 動態函數,傳聞數據庫引擎在思考本身如何高效的查詢數據的時候都要來這瞅瞅。excel

過高深的我並不會,目前我就看如下幾個,其餘參照MSDN

avg_fragmentation_in_percent =>當前索引碎片百分比 【若是碎片小於10%~20%,碎片不太可能會成爲問題,若是索引碎片在20%~40%,碎片可能成爲問題,可是能夠經過索引重組來消除索引解決,大規模的碎片(當碎片大於40%),可能要求索引重建。】

avg_page_space_used_in_percent =>全部頁中使用的可用數據存儲空間的平均百分比

page_count =>索引或數據頁的總數 

 select *  from  sys.dm_db_index_physical_stats(DB_ID() ,object_id('agent') ,NULL,NULL,NULL)


碎片的解決:

1.刪除索引並重建

  這種方式有以下缺點:

  索引不可用:在刪除索引期間,索引不可用。

  阻塞:卸載並重建索引會阻塞表上全部的其餘請求,也可能被其餘請求所阻塞。

  對於刪除彙集索引,則會致使對應的非彙集索引重建兩次(刪除時重建,創建時再重建,由於非彙集索引中有指向彙集索引的指針)。

  惟一性約束:用於定義主鍵或者惟一性約束的索引不能使用DROP INDEX語句刪除。並且,惟一性約束和主鍵均可能被外鍵約束引用。在主鍵卸載以前,全部引用該主鍵的外鍵必須首先被刪除。儘管能夠這麼作,但這是一種冒險並且費時的碎片整理方法。

  基於以上緣由,不建議在生產數據庫,尤爲是非空閒時間不建議採用這種技術。

  2.使用DROP_EXISTING語句重建索引

  爲了不重建兩次索引,使用DROP_EXISTING語句重建索引,由於這個語句是原子性的,不會致使非彙集索引重建兩次,但一樣的,這種方式也會形成阻塞。

CREATE UNIQUE CLUSTERED INDEX IX_C1 ON t1(c1)
WITH (DROP_EXISTING = ON)

缺點:

  阻塞:與卸載重建方法相似,這種技術也致使並面臨來自其餘訪問該表(或該表的索引)的查詢的阻塞問題。

  使用約束的索引:與卸載重建不一樣,具備DROP_EXISTING子句的CREATE INDEX語句能夠用於從新建立使用約束的索引。若是該約束是一個主鍵或與外鍵相關的惟一性約束,在CREATE語句中不能包含UNIQUE。

  具備多個碎片化的索引的表:隨着表數據產生碎片,索引經常也碎片化。若是使用這種碎片整理技術,表上全部索引都必須單獨確認和重建。

  3.使用ALTER INDEX REBUILD語句重建索引

  使用這個語句一樣也是重建索引,可是經過動態重建索引而不須要卸載並重建索引.是優於前兩種方法的,但依舊會形成阻塞。能夠經過ONLINE關鍵字減小鎖,但會形成重建時間加長。

  阻塞:這個依然有阻塞問題。

  事務回滾:ALTER INDEX REBUILD徹底是一個原子操做,若是它在結束前中止,全部到那時爲止進行的碎片整理操做都將丟失,能夠經過ONLINE關鍵字減小鎖,但會形成重建時間加長。

  4.使用ALTER INDEX REORGANIZE

  這種方式不會重建索引,也不會生成新的頁,僅僅是整理葉級數據,不涉及非葉級,當遇到加鎖的頁時跳過,因此不會形成阻塞。但同時,整理效果會差於前三種。

  4種索引整理技術比較:

特性/問題 卸載並重建索引 DROP_EXISTING ALTER INDEX REBUILD ALTER INDEX REORGANIZE
在彙集索引碎片整理時,重建非彙集索引 兩次
丟失索引
整理具備約束的索引的碎片 高度複雜 複雜性適中 簡單 簡單
同時進行多個索引的碎片整理
併發性 中等,取決於冰法用戶活動
中途撤銷 由於不使用事務,存在危險 進程丟失 進程丟失 進程被保留
碎片整理程度 中到低
應用新的填充因子
更新統計

 

 

參考:  SQL Server索引的維護 - 索引碎片、填充因子 <第三篇>

       msdn sys.dm_db_index_physical_stats (Transact-SQL)

相關文章
相關標籤/搜索