默认情况下,SQL Server是否在主键上构建索引? 如果是什么样的指数?如果没有哪种索引适合主键选择?
我使用SQL Server 2008 R2
谢谢。
答案 0 :(得分:16)
您可以轻松自行确定第一部分
create table x
(
id int primary key
)
select * from sys.indexes where object_id = object_id('x')
给出
object_id name index_id type type_desc is_unique data_space_id ignore_dup_key is_primary_key is_unique_constraint fill_factor is_padded is_disabled is_hypothetical allow_row_locks allow_page_locks
1653580929 PK__x__6383C8BA 1 1 CLUSTERED 1 1 0 1 0 0 0 0 0 1 1
编辑:还有一个我应该提到的案例
create table t2 (id int not null, cx int)
create clustered index ixc on dbo.t2 (cx asc)
alter table dbo.t2 add constraint pk_t2 primary key (id)
select * from sys.indexes where object_id = object_id('t2')
给出
object_id name index_id type type_desc is_unique data_space_id ignore_dup_key is_primary_key is_unique_constraint fill_factor is_padded is_disabled is_hypothetical allow_row_locks allow_page_locks has_filter filter_definition
----------- ------------------------------ ----------- ---- ------------------------------ --------- ------------- -------------- -------------- -------------------- ----------- --------- ----------- --------------- --------------- ---------------- ---------- ------------------------------
34099162 ixc 1 1 CLUSTERED 0 1 0 0 0 0 0 0 0 1 1 0 NULL
34099162 pk_t2 2 2 NONCLUSTERED 1 1 0 1 0 0 0 0 0 1 1 0 NULL
关于第二部分,没有黄金法则取决于您的个人查询工作量,以及您的PK是什么。
为了满足主键的单个查找,非聚集索引就可以了。如果您正在对范围进行查询,那么匹配的聚簇索引可以很好地满足这些要求,但覆盖非聚簇索引也可以满足要求。
您还需要特别考虑聚簇索引的索引宽度,因为它会影响所有非聚簇索引以及插入对页面拆分的影响。
我建议使用这本书SQL Server 2008 Query Performance Tuning Distilled来阅读有关这些问题的更多信息。
答案 1 :(得分:11)
是。默认情况下,会在所有主键上创建唯一的聚簇索引,但您可以创建一个唯一的非聚簇索引,而不是您喜欢的。
至于适当的选择,我会说,对于你创建的80-90%的表,你通常希望聚簇索引是主键,但情况并非总是如此。
如果您对“其他内容”进行大范围扫描,通常会使聚簇索引成为其他内容。例如,如果您有一个合成主键*,但是您有一个通常按范围查询的日期列,那么您通常希望该日期列成为聚簇索引中最重要的列。
*通常使用INT IDENTITY列作为表中的PK。
答案 2 :(得分:2)
是的,它默认在主键上构建聚簇索引。
答案 3 :(得分:2)
要直接,SQL会在PRIMARY KEY(PK)关键字上创建索引。该指数是一个独特的聚集指数。
sqlvogel在他的上面提到了一个重要的观点。您只能拥有一个“CLUSTERED”索引。如果您在宣布PK之前已经有一个PK,那么您的密钥将是NONCLUSTERED。这比这个问题的默认答案更详细一些。还应该注意PK不能有NULL值。
但是请注意,该索引可能会根据先前的约束或表上的索引而有所不同。此外,您可以根据编写代码的方式在创建时声明此索引的详细信息:
< table_constraint > ::= [ CONSTRAINT constraint_name ]
{ [ { PRIMARY KEY | UNIQUE }
[ CLUSTERED | NONCLUSTERED ]
{ ( column [ ASC | DESC ] [ ,...n ] ) }
[ WITH FILLFACTOR = fillfactor ]
[ ON { filegroup | DEFAULT } ]
]
示例:
CREATE TABLE MyTable
(
Id INT NOT NULL,
ForeignKeyId INT REFERENCES OtherTable(Id) NOT NULL,
Name VARCHAR(50) NOT NULL,
Comments VARCHAR(500) NULL,
PRIMARY KEY NONCLUSTERED (Id, ForeignKeyId)
)
答案 4 :(得分:1)
在表中已经定义了索引
的情况下,不会出现这种情况答案 5 :(得分:1)
我只是遇到了同样的困惑,刚刚创建了以下脚本进行测试:
create database mytest
go
use mytest
go
create table x
(
id int primary key
)
go
create table y
(
id int
)
go
select * from sys.indexes where object_id = object_id(N'x') or object_id=object_Id(N'y')
go
第一个表x有主键得到聚集索引,而表y没有得到任何 索引,因为没有主键。
确认以下关于聚集索引的观点:
当我们创建具有主键的表时,将创建聚簇索引 默认
当我们创建没有主键的表时,聚集索引不会 创建。
将有单个聚簇索引,因为它取决于索引键 价值。表中数据行的缩短只能在一个中 订单基于索引键值。