为什么在弱实体中需要单独的索引?

时间:2012-11-21 09:44:23

标签: sql-server entity-relationship

我是SQLServer的新手,有一件事让我感到困扰。希望你们中的一个人能够向我解释会发生什么。

当我在索引过程中运行活动监视器时,我发现包括弱实体在内的一些查询花费的时间比预期的要长 - 甚至更奇怪 - SQLServer建议在表单的弱实体上创建索引

CREATE NONCLUSTERED INDEX [<INDEXNAME>]
ON [dbo].[<TABLE>] ([<ID1>])
INCLUDE ([<ID2>])
GO

这样做(实际上我将两个列编入索引,但我认为结果几乎相同)真正提高了查询速度(至少从我在Activity监视器中看到的那样)。

CREATE UNIQUE NONCLUSTERED INDEX [<INDEXNAME>] ON [dbo].[<TABLE>] 
(
    [<ID1>] ASC,
    [<ID2>] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

我现在的问题是:SQLServer是否忽略聚集索引?如果是,为什么?我可以以某种方式修复它吗?对我来说,添加另一个实际上应该与主键索引具有完全相同内容的索引似乎很奇怪。

1 个答案:

答案 0 :(得分:2)

可能有多种原因 - 向我们展示您的聚集索引的定义以澄清。

如果您的聚簇索引位于ID2,ID1上,并且您在查询中选择了两个列,但在where子句中使用了ID1,那么这个新的非聚簇索引可以更快地运行。

如果你只在1列上有非聚集索引但是选择了两列,那么它必须转到聚簇索引来查找数据,因此在这种情况下将第二列添加为INCLUDEd列甚至是第二列索引列避免SQL服务器必须触摸数据页。

另一方面,如果聚集索引的顺序相同,则可以是以下任何一种:

  1. 您的聚集索引的填充因子 - 如果填充因子较低,则数据会分布在比所需数据页更多的数据页上,并且可能比从更密集填充的非聚集索引中读取数据
  2. 聚集索引所在的文件组(最终是磁盘) - 如果不同,查询优化器可能会识别聚簇索引磁盘上的高争用或慢速搜索速度
  3. 您已将顺序数据插入到聚簇索引中,聚集索引b-tree现在是双面的
  4. 表中发生了很多插入操作,导致许多页面拆分,导致数据在聚集索引上不是物理顺序
  5. 您的聚簇索引不是唯一的 - 在这种情况下,SQL服务器会向聚簇索引添加一个uniquifier,使其更大,因此读取的数据更多,因此比同等的非聚集索引更慢
  6. 您的聚集索引仅在1列(见下文)
  7. 如果您的聚簇索引在1列(例如ID1)上,则索引数据是对索引的2个逻辑读取,但ID2列数据在索引的叶子上,读取深度为3。

    对于等效的非聚集索引,它只需要2次逻辑读取,因为它不必访问数据页,这意味着非聚集索引将快1/3。

    查看聚簇索引和非聚簇索引的存储方式:

    Clustered Index Structures

    Non-Clustered Index Structures

    让我知道它是哪个!