0

我的数据库中有几个表是父子关系。例如:

CREATE TABLE [dbo].[cntnr_header] 
(
    [cntnr_id]            [dbo].[uid]     NOT NULL,
    CONSTRAINT [pk_cntnr_header] PRIMARY KEY CLUSTERED ([cntnr_id] ASC),
);

CREATE TABLE [dbo].[cntnr_content] 
(
    [cntnr_content_id]  [dbo].[uid]       NOT NULL,
    [cntnr_id]          [dbo].[uid]       NOT NULL,
    CONSTRAINT [pk_cntnr_content] 
       PRIMARY KEY CLUSTERED ([cntnr_content_id] ASC),
    CONSTRAINT [fk_cntnr_content_cntnr_header] 
       FOREIGN KEY ([cntnr_id]) 
       REFERENCES [dbo].[cntnr_header] ([cntnr_id]),
);

目前,如您所见,cntnr_id表中的外键上没有索引cntnr_contentcntnr_content_id我运行了调优向导,实际上我看到它建议为两者和cntnr_id表添加一个非聚集索引cntnr_content。我不太明白这一点,因为cntnr_content_id已经是聚集索引。为什么会推荐这样的索引?

CREATE NONCLUSTERED INDEX [_dta_index_cntnr_content_7_821577965__K1_K2] ON [dbo].[cntnr_content]
(
    [cntnr_content_id] ASC,
    [cntnr_id] ASC
)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]

我认为我可能应该cntnr_id在此表中添加一个非聚集索引。

这种情况有推荐的做法吗?我是否应该始终添加具有此类关系的某些索引?

许多查询要么将这两个表连接在一起,cntnr_id要么cntnr_content通过指定cntnr_id. 这也是一个更新/删除重表。更新和删除总是在主键 ( cntnr_content_id) 上完成。

4

2 回答 2

5

聚集索引以二叉树的形式物理存储在磁盘上。通常,它们非常适合读取繁重的工作负载。

探查器建议您不要在 cntnr_content 表上使用非聚集索引的原因是因为您通常会使用外键访问该表上的数据。

在这种情况下,主键上的聚集索引没有用处,因为数据以使用外键时难以找到的方式分布在磁盘上。这就是为什么它建议使用非聚集索引。

更改为非聚集索引允许数据库选择更适合通过外键查找的磁盘格式。当然,这样做会影响在主键上查找的速度,所以这是一种权衡——在一种情况下你会获得更快的速度,但在另一种情况下会牺牲一些速度。

于 2013-08-02T19:01:03.020 回答
0

cntnr_id 上的非聚集索引显然是针对外键的,因此如果您尝试从头表中删除一个,则不需要表扫描。

也适用于您按标题查找的主要用例。

在 cntnr_content_id 上单独拥有一个非聚集索引确实没有多大意义。两个 (cntnr_id, cntnr_content_id) 上的复合非聚集索引(按此顺序)如果覆盖可能是有意义的,因为它比聚集索引更窄。

于 2013-08-02T19:07:48.673 回答