主键上的默认索引

时间:2010-07-20 16:14:52

标签: sql-server primary-key indexing

默认情况下,SQL Server是否在主键上构建索引? 如果是什么样的指数?如果没有哪种索引适合主键选择?

我使用SQL Server 2008 R2

谢谢。

6 个答案:

答案 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没有得到任何   索引,因为没有主键。

确认以下关于聚集索引的观点:

  • 当我们创建具有主键的表时,将创建聚簇索引 默认

  • 当我们创建没有主键的表时,聚集索引不会 创建。

  • 将有单个聚簇索引,因为它取决于索引键 价值。表中数据行的缩短只能在一个中 订单基于索引键值。