1. 程式人生 > >SQL Server 索引碎片產生原理重建索引和重新組織索引 SQL Server索引的維護 - 索引碎片、填充因子 <第三篇>

SQL Server 索引碎片產生原理重建索引和重新組織索引 SQL Server索引的維護 - 索引碎片、填充因子 <第三篇>

資料庫儲存本身是無序的,建立了聚集索引,會按照聚集索引物理順序存入硬碟。既鍵值的邏輯順序決定了表中相應行的物理順序

多數情況下,資料庫讀取頻率遠高於寫入頻率,索引的存在 為了讀取速度犧牲寫入速度

頁 為最小單位 8kb

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

內部碎片 資料庫頁內部產生的碎片,外部反之

碎片的產生:

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

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

且一般情況下SQL Server資料庫預設設定有20%的填充因子

(可設定),既新建頁80%存資料,20%為update和insert預留。

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

檢視碎片情況:

用到這個極重要的 sys.dm_db_index_physical_stats 動態函式,傳聞資料庫引擎在思考自己如何高效的查詢資料的時候都要來這瞅瞅。

太高深的我並不會,目前我就看以下幾個,其他參照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)