在SQL Server里禁用聚集索引——真的好么?


有人問了我一個最有意思的問題:“你能禁用聚集索引么?

對這個問題,我先是嚇了一跳,因為我從未想過禁用聚集索引,因為聚集索引代表表數據,對這個最有趣問題,我立即答道:“我認為可以,但是...

好吧,我們現在來討論下“但是”。你禁用聚集索引,但我真的不知道SQL Server會如何反應,因此我們來試驗下。

(以下代碼運行在AdventureWorks2008R2數據庫)

1 -- Let's disable a Clustered Index
2 ALTER INDEX PK_Person_BusinessEntityID ON Person.Person DISABLE
3 GO

哈!語句還是可以正常執行的!但是你收到很多不同的外鍵約束也被禁用的警告。

好,我們已經禁用了表的聚集索引,但我們也有效的禁用了表本身。我們對禁用的聚集索引運行一個簡單的SELECT語句。

1 -- Let's run a SELECT statement against the disabled Clustered Index
2 SELECT * FROM Person.Person
3 GO

這下玩完了!!!查詢處理器無法生成計划,我們弄壞了我們的SQL語句。

當你開始考慮它的時候,很能想到這是有道理的:我們禁用了聚集索引,也禁用了表本身!但這不應該真的有關系,因為表上有非聚集索引,也可以作為我們獲取數據的路徑。

我們再想下。我們是否可以通過非聚集索引來訪問表數據?理論上是可以的,只要選擇的非聚集索引是覆蓋非聚集索引。如果你通過從聚集索引的書簽查找來請求一些其它列,你還是會有大問題,因為聚集索引已經禁用。因此我們來通過查詢sys.index來看下非聚集索引的狀態:

1 SELECT object_id , name ,index_id ,type ,type_desc , is_disabled  FROM sys.indexes WHERE object_id=OBJECT_ID('Person.Person')

哇!我們所有的的非聚集索引也被禁用了!現在根本沒有方法訪問我們的數據了。這是完全有道理的,因為不然的話會引入需要書簽查找的巨大問題。現在我們通過禁用聚集索引已經完全把表下線了!

怎么恢復表在線呢?簡單:我們需要重建我們的聚集索引:

1 -- Let's rebuild the Clustered Index
2 ALTER INDEX PK_Person_BusinessEntityID ON Person.Person REBUILD
3 GO

很簡單,是不是?但當我們再次查詢sys.index時,我們會看到我們的非聚集索引“還是禁用的”

因此我們“也要”重建我們的非聚集索引,讓它們恢復在線。

教訓:絕不禁用表的聚集索引!

感謝關注!

原文鏈接:

http://www.sqlpassion.at/archive/2016/04/11/disabling-clustered-indexes-in-sql-server-a-really-good-idea/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM