2013-08-02 73 views
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_content外键cntnr_id的索引。我运行了调整向导,并且实际上看到它表示在cntnr_content表上cntnr_content_idcntnr_id之间添加了非聚集索引。我不太明白这一点,因为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_idcntnr_content进行选择。这也是一个更新/删除繁重的表格。更新和删除总是在主键上完成(cntnr_content_id)。

+2

关于外键的索引通常很有用,但要谨慎使用诸如“总是”和“从不”等术语。在这种情况下,它很大程度上不取决于表本身的结构或它们之间的关系,而是如何查询数据。 –

+0

@AaronBertrand我在底部添加了一些其他信息,通常描述如何查询此表,但我也很好奇为什么调整顾问会在这两列上建议非聚集索引。 –

+1

好吧,所以如果你的问题是,“这种情况下的这个外键的索引是否有用?”答案是,“可能,是的。”你需要测试。如果问题是,“所有外键上的索引总是有用吗?”答案是不。 –

回答

2

聚簇索引作为二叉树物理存储在磁盘上。通常他们很适合阅读繁重的工作量。

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

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

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

+1

那么,我不会说“更改为非聚集索引” - 聚集索引可能非常有用的其他查询,不应该被删除恕我直言。可以在不删除任何现有索引的情况下添加非聚集索引。 –

+0

你是对的,它可能对其他查询有用。我只是解释了探查器用来达到推荐的逻辑。 –

0

cntnr_id上的非聚簇索引显然是外键,所以如果你试图从头表中删除一个,它不需要表扫描。

同样适用于您正在查找标题的主要用例。

在cntnr_content_id上拥有一个非聚集索引本身没有什么意义。 (cntnr_id,cntnr_content_id)(按该顺序)的复合非聚簇索引在覆盖时可能有意义,因为它将比聚簇索引更窄。

+0

那么cntnr_content_id也有很多更新/删除操作。我认为在这些情况下这仍然是有益的。 –

+0

@ColeW不太可能。这是CI中的第一列,CI确实需要更新或删除。你知道表是一个堆还是一个聚集索引?聚集索引不是与表格分开的东西。它描述了如何根据聚簇索引键和树叶中的非关键数据在B树中构建表数据。然后,非聚簇索引是独立的b-树,指向聚簇索引b-tree中的堆书签或聚簇索引键。 –