我们的数据库由许多表组成,其中大多数使用整数代理键作为主键。这些主键中约有一半位于标识列上。
数据库开发始于 SQL Server 6.0。
从一开始就遵循的规则之一是,避免根据递增键创建聚集索引,正如您在这些索引优化技巧中找到的那样。
现在使用 SQL Server 2005 和 SQL Server 2008,我强烈的印象是情况发生了变化。同时,这些主键列是表的聚集索引的完美首选。
对于具有标识列的表,是否应该为标识列创建聚集或非聚集 PK/唯一索引?
原因是将为查询创建其他索引。使用非聚集索引(在堆上)并返回索引未涵盖的列的查询将使用较少的逻辑 I/O (LIO),因为没有额外的聚集索引 b 树查找步骤?
create table T (
Id int identity(1,1) primary key, -- clustered or non-clustered? (surrogate key, may be used to join another table)
A .... -- A, B, C have mixed data type of int, date, varchar, float, money, ....
B ....
C ....
....)
create index ix_A on T (A)
create index ix_..... -- Many indexes can be created for queries
-- Common query is query on A, B, C, ....
select A, …Run Code Online (Sandbox Code Playgroud) performance sql-server database-internals index-tuning heap performance-tuning
我最近被指派管理 SQL Server 2016 中的数据库,我发现数据库中有许多表具有非唯一聚集索引,导致非聚集主键索引。
我知道上述显然是允许的,但并不理想(特别是对于大表),也许在某些情况下,这是有道理的,但此类表的数量告诉我,这更像是粗心的表定义的结果。
例如,一个名为的表Transaction将有一个带有以下键的聚集索引:date, is_deleted. 此外,该表将在名为 的列上有一个非聚集主键id。
现在,其中一些表非常大,并且上面有许多外键引用,所以我想出了以下步骤,在 Aaron 在此线程中的回答的帮助下更改所有这些表无法删除非 PK 索引,因为它是在外键约束中引用:
id列创建主键集群约束我知道对于大表,我需要找到一个维护窗口来执行更改,但是您是否发现上述解决方案有任何我没有想到的问题或陷阱?这种方法会导致非聚集索引的其余部分出现碎片吗?
涉及很多表,我想确保我不会触发任何副作用。