Heap Table 重建時會造成資料表中所有的索引一併重建

Heap Table 重建時會造成資料表中所有的索引一併重建

7月參加SQL PASS聚會,講師許致學老師在舉例Heap Table的缺點時

有提到當該資料表為Heap型態時,我們對該資料表做Rebuild時,該

資料表中所有的索引會一併被重建,因為Heap資料表中資料是根據所

謂Row Id排序,而資料表重建會導致Row Id變動,而索引中會儲存該

Row Id,因此牽一髮而動全身。

 

而有建立叢集的資料表排序是根據我們訂定的欄位來排,因此即使我們

Rebuild資料表,所有資料依然是依循欄位內容排序。所以就不會導致

索引需要重建。但如果是更動叢集的欄位則還是會引發所有的索引重建。

 

我們來做個小LAB吧,以下的CODE是前置作業


/**
建立兩張資料表,HeapTable及ClusteredTable
HeapTable不建立Clustered Index
ClusteredTable建立Clustered Index
**/
Create Table HeapTable(id int identity,name char(10))
Create Table ClusteredTable(id int identity Primary Key,name char(10))
GO


/**
新增資料進這兩張資料表HeapTable及ClusteredTable
**/
Insert Into HeapTable Values('Rcok');
Insert Into ClusteredTable Values('Rcok');
GO
Insert Into HeapTable Select name From HeapTable;
Insert Into ClusteredTable Select name From ClusteredTable;
GO 10


/**
在這兩張資料表HeapTable及ClusteredTable都建立
一個非叢集所引
**/
Create Index IX_Name On HeapTable(name);
Create Index IX_Name On ClusteredTable(name);
GO

 

完成前置作業後,我們來思考該如何知道索引有被重建過呢?我爬了很多文,但似乎

都沒有查詢索引Rebuild時間的方法(如果您知道的話,歡迎指教)。因此我拐了個彎

,我們都知道當索引被重建後其相對應的統計資訊也會一併更新。而統計資訊何時

被更新就有方法查出來了。等一下我們利用SQL內建的函數STATS_DATE來查詢。

也可以利用 DBCC SHOW_STATISTICS 來查詢。

 

如下圖所示我們先看一下兩張資料表的IX_name統計資訊更新時間是何時。可以看出

大約是晚上9點30分。

1

 

 

接下來我們刪除兩張資料表各一半的資料,刪除完畢後再重新Rebuild兩張資料表。

2

 

 

Rebuild兩張資料表後,我們再來看一下統計資訊的差異。如下圖紅色圈選處,HeapTable

的IX_name統計資訊更新時間變成晚上10點32分,而ClusteredTable上的依然沒變。

3

 

 

透過上面簡單的LAB,我們可以知道Heap資料表重建時會連同所有索引一起重建。

因此日後處理這樣的資料表要非常小心,如果該資料表資料量非常大的話,在Rebuild時

可能會造成嚴重的效能問題,交易紀錄檔也會成長得非常驚人。

 

我是ROCK

rockchang@mails.fju.edu.tw