在分區表上創建的索引分為:分區對齊索引(Aligned Index)和非對齊索引。對齊索引是指索引結構的分區和基礎表的分區相同,這意味着,在表的一個分區上創建的索引,索引結構也在同一個分區中。索引結構在每個分區中都是獨立存儲和維護的,如果索引結構和表結構在同一個分區(也就是在同一個文件組上),那么索引是與基礎表對齊的索引。創建對齊索引,並不意味着必須使用相同名稱的分區scheme,只要分區schem使用的分區邊界和每個分區存儲的文件組相同,這兩個分區schem是等價的,使用等價的分區scheme創建的索引和基礎表是對齊的。
索引對齊能夠提升查詢性能,能夠實現分區的隔離和分區的切換(switch)操作,分區的隔離能夠避免分區列上的競爭,從而有效避免死鎖;通過分區的切換和數據表的截斷(TRUNCATE TABLE)這一操作組合,使得在刪除海量數據表上的一個分區時,能夠瞬間完成,而分區對齊的好處不止如此,建議創建對齊索引。
在分區表上創建索引,如果沒有使用ON子句指定文件組,那么,默認創建的索引是分區索引,分區scheme和基礎表相同,索引的每一個分區和基礎表對應的分區存儲在同一個文件組,這就是所謂的對齊索引。另外一種情況,基礎表是沒有分區的,而索引是分區的,在這種情況下創建分區索引時,需要在CREATE INDEX的ON子句中指定分區scheme。
在分區表上創建對齊索引,分區列必須包含在聚集索引鍵,唯一索引鍵(唯一索引,主鍵約束,唯一約束)中;對於對齊的非聚集索引(不是唯一索引),分區列可以是包含列,也可以是索引鍵。
一,對齊的非聚集索引
創建分區函數,分區scheme,分區表和分區索引:

-- create parition function create partition function pf_int_left (int) as range left for values (10,20); --create partition scheme create partition scheme ps_int_left as partition pf_int_left to ([primary], [primary], [primary]); -- create partition heap create table dbo.dt_partitiontable ( ID int not null, code int not null, name varchar(10) null, ) on PS_int_Left(ID);
在分區表上創建非聚集索引,在默認情況下,創建的是對齊索引:
--create nonclustered index create nonclustered index idx_partition_Code on dbo.dt_partition_table(Code)
在分區表上創建輔助索引(不是唯一索引和聚集索引)時,默認創建的是對齊索引。如果索引鍵中包含分區列,並且使用相同的分區scheme,那么創建的索引就是和基礎表對齊的索引。如果沒有顯式指定分區scheme,或者索引鍵中沒有包含分區列,SQL Server自動向輔助索引中添加分區列,作為包含列。
二,對齊的聚集索引
在創建聚集索引時,SQL Server保證分區列是聚集索引鍵。如果沒有顯式指定分區列為聚集索引鍵,那么SQL Server會自動添加分區列作為索引列,注意:聚集索引沒有包含列。
在創建聚集索引的語句中,如果沒有顯式指定分區列和分區scheme,那么SQL Server 使用基礎表上的分區列和分區scheme創建聚集索引,SQL Server自動把分區列添加到索引鍵中。
create clustered index cidx_partition_table_code on dbo.dt_partition_table(code)
創建聚集索引的目的是為了從物理上組織數據表的存儲結構,由於,對表分區影響表的物理結構,使得表的數據按照物理存儲順序存儲,因此,SQL Server內部強制分區列必須是聚集索引的一列。
三,對齊的唯一索引
在創建唯一索引(唯一索引和唯一約束)時,唯一索引鍵中必須顯式包含分區列,SQL Server 強制每個分區上的索引列都是唯一的。這意味着,在創建對齊的唯一索引時,不管創建的是聚集索引還是非聚集索引,必須在唯一索引鍵中顯式指定分區列。
--drop clustered index drop index cidx_partition_table_code on dbo.dt_partition_table --create unique clustered index create unique clustered index cidx_partition_table_code on dbo.dt_partition_table(code) --create unique nonclustered index create unique nonclustered index idx_partition_table_code on dbo.dt_partition_table(code)
由於唯一約束在底層使用唯一索引來保證唯一性,因此,在分區表上創建的唯一約束,必須顯式包含分區列。
如果沒有顯式指定分區列,SQL Server會拋出錯誤消息:
Column 'ID' is partitioning column of the index 'xxx'. Partition columns for a unique index must be a subset of the index key.
四,對齊的主鍵約束
在SQL Server 內部,主鍵約束(Primary Key)自動創建唯一索引(unique index),只不過索引列必須是非空的(not null),因此,在創建主鍵約束時,不管創建的是聚集索引還是非聚集索引,主鍵必須顯式包含分區列。
-- create pk nonclustered index alter table dbo.dt_partition_table add constraint PK__partition_table_code_nonclustered primary key nonclustered (code) -- create pk clustered index alter table dbo.dt_partition_table add constraint PK__partition_table_code_clustered primary key clustered (code)
如果沒有顯式指定分區列,SQL Server會拋出錯誤消息:
Column 'ID' is partitioning column of the index 'PK__xxxx'. Partition columns for a unique index must be a subset of the index key.
五,非對齊索引
也可以在分區表上創建非對齊索引,所謂非對齊索引,是指索引的分區scheme和基礎表的分區scheme不同,其物理存儲結構也不同。在默認情況下,SQL Server在分區表上創建的是對齊索引,因此,要創建非對齊索引,必須在CREATE INDEX命令中顯式指定索引結構存儲的數據空間,數據空間是文件組,或者跟基礎表不同的分區scheme。這意味着,非對齊索引存儲在特定的文件組上,或者跟其基礎表有不同的分區scheme。
create nonclustered index idx_partition_table_code on dbo.dt_partition_table(code) on file_group_name;
六,查看索引的元數據
使用系統視圖:sys.indexes 查看索引的元數據:
select i.name as index_name ,i.index_id ,i.type_desc as index_type ,ds.name as data_space ,ds.type_desc as data_space_type ,i.is_unique ,i.is_unique_constraint ,i.is_primary_key ,ic.index_column_id ,col_name(ic.object_id,ic.column_id) as column_name ,ic.key_ordinal ,ic.partition_ordinal ,ic.is_included_column from sys.indexes i inner join sys.index_columns ic on i.object_id=ic.object_id and i.index_id=ic.index_id inner join sys.data_spaces ds on i.data_space_id=ds.data_space_id where i.object_id=object_id('table_name','U') order by i.index_id ,ic.index_column_id
參考文檔: