SQL Server 2005 - 索引的維護作業 - Part 1

摘要:SQL Server 2005 - 索引的維護作業 - Part 1

或許您認為,索引建立之後,就無事 一身輕了,其實不然,您仍然必須時時去維護它們,以確認它們仍保有最佳效率。比方說,資料表經過一段時日的使用後,資料必定會變得片段,此狀況可能會影響 系統執行效率,我們必須學會如何改善此情況;再者,基於作業上的需求與變更,可能必須去改變索引的相關設定…凡此種種都屬於索引維護作業的範疇。本文將指 導大家使用相關工具與陳述式來完成索引的各項維護作業。

變更索引的相關設定

索引建立後,您可以隨時視需要變更其相關設定,比方說,您可以更改其名稱、改變鍵值欄、在叢集與非叢集間切換、變更存放的檔案群組‧‧‧等等。不過筆者必須提醒大家,如果資料表擁有極多筆資料記錄,改變索引的某些設定可能必須耗費極長的時間,此點大家不可不察。

欲以視覺化操作來變更索引的相關設定,請採用下列兩種方法之一:

■ 使用「索引/索引鍵」視窗

操作步驟如下所示:

1. 開啟資料表的結構定義畫面,使用滑鼠按一下工具列中的「管理索引和索引鍵」按鈕 。

2. 當「索引/索引鍵」視窗開啟後,從「選取的 主/唯一索引鍵或索引」下拉式清單中選取所需的索引,並變更其各項設定。

3. 反覆步驟 2 的操作,直到您已將需要變動之各個索引設定完畢後,按下「關閉」按鈕。

4. 從「檔案」功能表中選取「儲存<資料表的名稱>」指令將資料表存檔。

■  使用「索引屬性」視窗

操作步驟如下所示:

1. 於「物件總管」中您欲變更其索引的名稱上,按一下滑鼠右鍵,接著選取「屬性」指令來開啟索引的「索引屬性」視窗。

2. 按一下「選取頁面」中的選項頁面來切換到不同的設定頁面,根據您的需要修改索引的設定。

3. 反覆步驟 2 的操作,直到您已完成各個需要變動之索引的設定後,按下「確定」按鈕,此時 SQL Server 就會將您所變動的索引加以存檔。

4. 反覆步驟 1~3 的操作,直到您已完成各個需要變動之索引的設定。

筆者必須提醒大家,上述兩種做法中,只有使用「索引/索引鍵」對話視窗才能更改索引的名稱。其實您可以在「物件總管」中欲更名其索引的名稱上,按一下滑鼠右鍵,接著選取「重新命名」指令來更改索引的名稱。如果您想要以程式控制方式更改索引的名稱,請使用系統預存程序 sp_rename。比方說,我們想要將資料表「我的資料表」之索引「我的既有索引」的名稱更改成「我的新索引」,請執行下列陳述式:

EXEC sp_rename '我的資料表.我的既有索引', '我的新索引', 'INDEX'

附註:
系統預存程序 sp_rename 的用法已在「SQL Server 2005 完全實戰」一書的第五章詳細介紹過,於此不再贅述。

或許您正思考著,我們能否以程式控制方式來變更索引的相關設定呢?答案當然是肯定的。其實使用「索引/索引鍵」視窗來變更索引相關設定的方法,就是先使用 DROP INDEX 陳述式將索引刪除,再使用 CREATE INDEX 陳述式建立一個符合目前設定的索引。顯然此做法是拐個彎來變更索引的相關設定,它雖然行得通,但是速度卻非常慢。大家別忘了,當您刪除一個叢集索引,此資 料表的所有非叢集索引都必須重建一次,同樣的,當您建立一個叢集索引,此資料表的所有非叢集索引亦必須重建一次,因此如果您採取先刪除再建立的方式去變更 一個叢集索引的相關設定,將導致資料表的所有非叢集索引被重建「兩次」,其間所造成的速度低落是極其嚴重的(資料表的資料記錄愈多,索引建立速度愈慢)。

以程式控制方式來變更索引之相關設定的正統做法,是使用加入關鍵字 WITH DROP_EXISTING=ON CREATE INDEX 陳述式。其實這也是以重建索引的方式來變更索引的相關設定,但它的重建作業卻是在單一步驟內完成,而在單一步驟內重建索引有下列好處:

■ 使得 SQL Server 僅僅去重新組織一個既存的索引,而不需要先刪除再重建,當然就不會發生所有的非叢集索引被重建兩次的狀況。

■  它會使用既存之索引中已排序的資料,不需要將資料再排序一次。除非這個索引陳述式是要建立一個非叢集索引,同時 ONLINE 選項設被指定為 OFF

■  此法能直接更改 PRIMARY KEYUNIQUE 條件約束之索引的相關設定。

當您使用關鍵字 WITH DROP_EXISTING 時,務必注意下列事項:

■  CREATE INDEX . . . WITH DROP_EXISTING 陳述式能夠將一個非叢集索引改變成一個叢集索引,但是不能將一個叢集索引改變成一個非叢集索引。

此外務必小心的是,雖然 CREATE INDEX . . . WITH DROP_EXISTING 陳述式能夠直接更改 PRIMARY KEYUNIQUE 條件約束之索引的相關設定,但是此法不能將 PRIMARY KEYUNIQUE 條件約束的索引從叢集索引變更成非叢集索引,亦不能將 PRIMARY KEYUNIQUE 條件約束的索引從非叢集索引變更成叢集索引。

■  使用 CREATE INDEX . . . WITH DROP_EXISTING 陳述式去變更一個叢集索引的相關設定時,需要資料表大小之 1.2 倍的剩餘空間來實際重組資料。

■  您不能使用 CREATE INDEX . . . WITH DROP_EXISTING 陳述式去變更系統資料表之既存索引的相關設定。

■  請注意,CREATE INDEX . . . WITH DROP_EXISTING 陳述式是去變更一個既存索引的相關設定,而不是去新建立一個索引,因此如果指定名稱的索引並不存在,將出現錯誤。

■  如果您已經停用叢集索引,在執行 CREATE INDEX . . . WITH DROP_EXISTING 陳述式時,就必須將 ONLINE 選項設為 OFF,此舉也將啟用被停用的叢集索引。

■ 如果您已經停用非叢集索引,而所要建立的新索引並未關聯到已經停用之叢集索引,在執行 CREATE INDEX . . . WITH DROP_EXISTING 陳述式時,不論 ONLINE 選項的設定是 ON 或是 OFF 都可以,此舉也將啟用被停用的非叢集索引。

變更索引的範例

在以下的執行步驟中,我們會先替資料庫「索引調校練習」中的資料表 Vfpman 建立一個索引,然後再變更此索引的相關設定:(「索引調校練習」資料庫已附於「SQL Server 2005 完全實戰」一書的範例光碟中)

1. 執行下列程式碼替資料表 Vfpman 建立一個索引:

CREATE NONCLUSTERED
  INDEX IX_Name_Vfpman ON Vfpman (name)
  WITH (PAD_INDEX = ON,FILLFACTOR = 80);

2. 下面的程式碼會更改前一個步驟所建立之索引的鍵值欄與填充係數,並使其成為一個唯一索引:

CREATE UNIQUE
  INDEX IX_Name_Vfpman ON Vfpman (name,tele,birthday)
  WITH (PAD_INDEX = ON,FILLFACTOR = 50,DROP_EXISTING = ON);

3. 下面的程式碼會更改索引的名稱:

EXEC sp_rename 'Vfpman.IX_Name_Vfpman','IX_NTB_Vfpman','INDEX';

待續......