非唯一聚集索引管理
我最近被分配管理 SQL Server 2016 中的數據庫,我發現數據庫中有許多表具有非唯一聚集索引,從而導致非聚集主鍵索引。
我知道上面顯然是允許的,但並不理想(特別是對於大表),也許在少數情況下,這是有道理的,但這樣的表的數量告訴我,這更像是粗心的表定義的結果。
例如,一個名為的表
Transaction
將有一個帶有以下鍵的聚集索引:date
,is_deleted
. 此外,該表將在名為 的列上具有非聚集主鍵id
。現在,其中一些表非常大,並且有許多外鍵引用,所以我想出了以下步驟來更改所有這些表,並藉助 Aaron 在此執行緒中的回答Unable to drop non-PK index because it is在外鍵約束中引用:
- 刪除表的聚集索引
- 刪除所有引用該表的外鍵約束
- 刪除表的目前主鍵約束
id
使用列創建主鍵聚集約束- 創建之前刪除的所有外鍵約束
- 可選 - 將以前的聚集索引創建為非聚集索引
我知道對於大型表,我需要找到一個維護視窗來執行更改,但是您是否發現上述解決方案的任何問題或陷阱是我沒有想到的?這種方法會導致其餘非聚集索引的碎片嗎?
涉及很多表格,我想確保我不會觸發任何副作用。
如果不知道您的查詢模式就很難回答這個問題,但是當刪除所有聚集索引並用其他東西替換它們時,您肯定會產生副作用。
我也不認為您認為擁有非唯一聚集索引是草率的表設計或根據定義是次優的,這不一定是正確的。
添加非唯一聚集索引時,
uniqueifier
如果鍵中有重複值,SQL Server 會在索引中添加一個 4 字節以確保鍵是唯一的。計算這個唯一性會增加一些成本,但不會太戲劇化。這個唯一性也必須在非聚集索引中,因為索引書籤必須指向單行。另一方面,您給出的範例可能是一個很好的聚集索引,具體取決於具體情況:
例如,一個名為 Transaction 的表將有一個帶有以下鍵的聚集索引:日期、is_deleted。此外,該表將在 id 列上有一個非聚集主鍵。
如果在同一日期有很多交易,這可能是一個非常好的設計決策,並且幾乎每個查詢都是
SELECT * FROM transactiontable WHERE date = <somedate> AND is_deleted=0
.如果必須使用非聚集索引並求助於鍵查找,這樣的查詢可能會受到嚴重傷害。
不可能說你會觸發什麼副作用,但你肯定會觸發一些,而且你這樣做的原因可能是錯誤的。
如果您堅持這樣做,請確保您首先在測試環境中對其進行測試,如果您這樣做了,您應該能夠判斷此方法是否有效以及是否會導致碎片(但這可能是您最少的擔心)。