Sql-Server

圍繞唯一索引 16 列最大值的任何方式

  • March 28, 2012

根據CREATE INDEX文件:

最多可以將 16 列組合成一個複合索引鍵。

我們有一個大約 18 列的表,需要形成一個獨特的組合。該表對性能敏感——我們很少更新值/插入記錄。我們只需要確保我們避免重複我們的記錄……並認為我們可以施加一個簡單的唯一性約束。

有任何想法嗎?如果有更好的方法,我願意完全避免唯一索引/約束。

添加一個組合了 18 個鍵的持久計算列,然後在計算列上創建一個唯一索引:

alter table t add all_keys as c1+c2+c3+...+c18 persisted;
create unique index i18 on t (all_keys);

請參閱在計算列上創建索引

另一種方法是創建索引視圖:

create view v 
with schemabinding
as select c1+c2+c3+...+c18 as all_keys
from dbo.t;

create unique clustered index c18 on v(all_keys);

請參閱創建索引視圖

兩種方法都允許部分鍵聚合:將 c1+c2+c3 聚合為 k1,將 c4+c5+c6 聚合為 k2 等。然後在 (k1, k2, …) 上索引/創建索引視圖。Thia 可能有利於範圍掃描(索引可用於在 c1+c2+c3 上進行搜尋。

當然,+我的範例中的所有操作都是字元串聚合,實際使用的運算符取決於所有這些列的類型(即,您可能必須使用顯式強制轉換)。

PS。由於唯一約束由唯一索引強制執行,因此對唯一索引的任何限制也將適用於唯一約束:

create table t (
   c1 char(3), c2 char(3), c3 char(3), c4 char(3),
   c5 char(3), c6 char(3), c7 char(3), c8 char(3),
   c9 char(3), c10 char(3), c11 char(3), c12 char(3),
   c13 char(3), c14 char(3), c15 char(3), c16 char(3),
   c17 char(3), c18 char(3), c19 char(3), c20 char(3),
   constraint unq unique
     (c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18));
go  


Msg 1904, Level 16, State 1, Line 3
The index '' on table 't' has 18 column names in index key list. 
The maximum limit for index or statistics key column list is 16.
Msg 1750, Level 16, State 0, Line 3
Could not create constraint. See previous errors.

但是,在持久計算列上創建約束是有效的:

create table t (
   c1 char(3), c2 char(3), c3 char(3), c4 char(3),
   c5 char(3), c6 char(3), c7 char(3), c8 char(3),
   c9 char(3), c10 char(3), c11 char(3), c12 char(3),
   c13 char(3), c14 char(3), c15 char(3), c16 char(3),
   c17 char(3), c18 char(3), c19 char(3), c20 char(3),
   all_c as 
       c1+c2+c3+c4+c5+c6+c7+c8+c9+c10+c11+
       c12+c13+c14+c15+c16+c17+c18 
       persisted
       constraint unq unique (all_c));
go  

顯然,持久化列會佔用磁碟空間,因此該方法可能不適用於非常大的表。索引視圖方法沒有這個問題,它只消耗索引的空間,而不是計算列索引的空間。

引用自:https://dba.stackexchange.com/questions/6647