Share via


SQL 問答集非叢集索引和保留權限

Saleem Hakani and Dan Carollo

非叢集索引及其用途

問:什麼是非叢集索引?使用它們有何利弊?

答:非叢集索引就好比一般書末的索引。書中所含的各項資訊在索引中依主題列出,並附有頁碼等指標,方便在書中的多個章節內找到所需資訊。另外,書籍索引資料所列的順序不等於在書中出現的順序,這一點跟非叢集索引一樣。如果您在資料表上有叢集索引,便可以指定項目的順序。否則,就無法確定順序。

除此之外,非叢集索引還有兩項限制:索引裡面只能包含 16 個資料行,而且索引鍵最大不得超過 900 個位元組。這是什麼意思呢?我們來看看,如果您希望在 MovieList 範例資料庫的 Movie 資料表內製作下列資料行的索引時,會發生什麼事:MovieTitle NVarchar(50), DirectorName NVarchar(50), ShortStory NVarchar(400)。

假設您發出下列陳述式來建立資料表:

Use MovieList;
CREATE INDEX Movie_IDX ON Movie(MovieTitle, DirectorName, ShortStory); 

這時會產生下列錯誤訊息:「警告!最大索引鍵長度是 900 個位元組。'Movie_IDX' 索引的最大長度是 1000 個位元組。有些大值的組合,是無法執行插入/更新作業的」。您會收到上列的訊息,是因為 "nvarchar" 資料型別每個字元會耗用 2 個位元組,而含有前三個資料行的索引,便超過了 900 個位元組的大小限制。

但是 SQL Server® 2005 推出之後,現在只要把資料行加入 INCLUDE 子句中,就可以克服這個問題了。如果您希望同時解決大小和資料行限制,這是非常實用的功能。您可以執行下列陳述式:

CREATE INDEX Movie_IDX ON Movie(MovieTitle, DirectorName) INCLUDE (ShortStory);

請注意,當您在建立索引期間使用 INCLUDE 子句時,資料庫引擎在計算索引鍵資料行或索引鍵大小的時候,並不會考慮非索引鍵資料行。

如需其他非叢集索引的實用資訊,請參閱<非叢集索引>,位於msdn2.microsoft.com/aa174537 和<使用非叢集索引>,位於 msdn2.microsoft.com/aa933130。如需將索引最佳化的秘訣,則請參閱 sql-server-performance.com/optimizing_ indexes.asp。

保留權限資料

問:當訂閱重新初始化時,該如何避免遺失權限?這個問題我遇過好幾次:當快照集重新初始化時,就會遺失所有授予的權限。

答:在預設的情況下,訂閱每次重新初始化時,訂閱資料庫中所有的物件全都會被捨棄然後重建。但是有兩種方法可以解決這種情況。

首先,您可以在重新初始化之後,重新套用所有的權限。當您手動設定權限時,最好把所有的物件/陳述式層級權限寫成指令碼,然後分開存放,這樣就可以在重新初始化訂閱之後,立即使用它們。

其次,您可以設定訂閱,讓它不要在每次重新初始化訂閱時,捨棄任何物件。您可以使用 SP_CHANGEARTICLE 系統預存程序,為 @PROPERTY 參數設定 PRE_CREATION_CMD 一值,以及為 @Value 參數設定 NONE、DELETE 或 TRUNCATE 的值。

另外,請在目的地物件區段中的 [發行項屬性] 對話方塊裡,選取 [不要變更現有物件,請刪除資料]。[如果發行項有資料列篩選器,請只刪除符合篩選的資料]。[請截斷現有物件中的所有資料的值]。請務必先在測試環境中試驗這個動作,如果需要進一步的協助,請查看《SQL Server 線上叢書》最新版本以取得最新資訊。

Saleem Hakani 身兼資深資料庫工程師、資深問題工程師,以及全球 Microsoft SQL Server 社群主管,他在資料庫系統方面有超過 14 年的經驗。他負責外部 SQL Server 社群網站,網址是 sqlcommunity.com,您可以透過電子郵件與他連絡:Saleem@sqlcommunity.com

Dan Carollo 在 Microsoft 的 Windows 防惡意程式碼研究與因應 (Windows Anti-Malware Research and Response) 小組擔任作業工程師和 SQL Server DBA。他在 SQL Server 擁有 MCT 認證。

© 2008 Microsoft Corporation and CMP Media, LLC. 保留所有權利;未經允許,嚴禁部分或全部複製.