天天看點

SQL Server誤區30日談-Day29-有關堆碎片的誤區

  本系列文章是我在sqlskill.com的PAUL的部落格看到的,很多誤區都比較具有典型性和代表性,原文來自T-SQL Tuesday #11: Misconceptions about.... EVERYTHING!!,經過我們團隊的翻譯和整理釋出在AgileSharp上。希望對大家有所幫助。

誤區 #29:可以通過對堆建聚集索引再DROP後進行堆上的碎片整理

Nooooooooooooo!!!

    對堆建聚集索引再DROP在我看來是除了收縮資料庫之外最2的事了。

    如果你通過sys.dm_db_index_physical_stats(或是老版本的DBCC SHOWCONTIG)看到堆上有碎片,絕對不要通過建立聚集索引再删除聚集索引來整理堆碎片。好的做法應該是建立聚集索引之後不再删除,已經有非常多的資料闡述如何選擇一個理想的聚集索引鍵--窄,很少變動,唯一,自增。Kimberly有一篇文章對此做了一個總結:Ever-increasing clustering key - the Clustered Index Debate..........again!(注意,是基于SQL Server 2005版本),對此我也有一個例子:An example of a nasty cluster key。

    你也可以在SQL Server 2008中通過ALTER TABLE ... REBUILD來清除堆碎片,但這個做法和建立聚集索引後再删除同樣邪惡。

    如果你想問為什麼我對此甚有成見?好吧,那我解釋一下:非聚集索引中每一行都會指向一個RID或是聚集索引鍵的連結(詳情請看:What Happens if I Drop a Clustered Index?),這個連結會以下面兩種方式之一出現:

    如果聚集索引所在的表是堆,那麼這個連結就是一個RID。

    如果聚集索引所在的表是聚集索引,那麼這個連結就是聚集索引鍵。

    如果你希望對此有更多了解,請看文章底部的連結。

    是以不難看出,如果你希望将堆變為聚集索引,那麼非聚集索引的所有RID就失效了,是以所有的非聚集索引都需要被重建。同樣,如果删除聚集索引鍵,那麼所有非聚集索引上存儲的聚集索引鍵都會失效,是以也需要重建所有的非聚集索引。

    簡單點說,如果你建立再删除聚集索引後,所有的非聚集索引都會被重建兩次。

    如果你使用SQL Server 2008的ALTER TABLE ... REBUILD來整理堆碎片,那麼同樣也需要重建所有的非聚集索引,因為所有的RID都會變動。

    那麼,如果對于“重建”聚集索引呢?這取決于SQL Server的版本以及你是進行rebuild索引亦或是改變索引。一個常見的誤區是對表進行分區将會改變聚集索引鍵,但事實上不會。對于那些會引起非聚集索引重建的操作,請看如下清單:Indexes From Every Angle: What happens to non-clustered indexes when the table structure is changed?。

本文轉自CareySon部落格園部落格,原文連結:http://www.cnblogs.com/CareySon/archive/2013/02/17/2913939.html,如需轉載請自行聯系原作者