好的,我需要再次拼出这个。我已经在线阅读了这些文章,但我还没有找到明确的答案。
在SQL Server 2008中,我有一个“核心”表,其中包含大约50,000条记录和大量读取活动,在所有查询中以相同的方式使用。此数据每月更新一次,每秒读取数百次。
数据在字段上具有聚簇索引,因为它们经常被访问。假设聚集索引是:
CLUSTERED INDEX
Field1 int
Field2 int
Field3 int
Field4 int
Field5 int
现在,没有比这更多的数据了,所以将额外的几列放入“包含的列”是有意义的,但是SQL Server不允许在聚集索引上包含列。 / p>
因此,我们有第二个索引,其字段与Clustered Index基本相同,其他列为“Included Columns”。但是,从我读过的内容来看,我认为这可能是多余的?
COVERING INDEX(非群集)
Field1 int
Field2 int
Field3 int
Field4 int
Field5 int
包含栏目
Field6 varchar(96)
Field7 varchar(96)
非聚集索引ALREADY是否具有其中定义的聚簇索引的列?
如果是这样,那么如何使用NO列创建第二个索引(除了已经在聚簇索引中的内容)?换句话说,我想说“这个索引与聚集索引完全相同......带有几个包含的列”。
或者,将所有列放入聚集索引(包括不识别记录的两个列)会更好吗? varchar列确实更频繁地更新(每天几次而不是每月一次),所以我希望将它们保留在聚集索引之外,但我认为它们足够深,它们不会影响索引树足以在发生更改时导致任何重新平衡。
那么,有没有一种有效的方法来设置这些索引,以便通过索引可以获得该表的所有列而无需返回到表中?
答案 0 :(得分:5)
是 - NonClustered Index通过群集密钥访问表中的数据(当表具有群集密钥时,以及当没有群集密钥时访问行ID),因此它将自动包含聚集索引字段。这也是为什么更改聚簇索引会强制重建所有非聚集索引的原因。
如果该索引满足大量查询,则包含2个字段的附加NC索引可能有效,但我不确定是否正在解决正确的问题。
在Clustered Key中包含2个以上的字段并不理想,现在在NC索引中确认,您可以看到该表上的每个索引都包含其中的每个索引的群集密钥。
这是您希望群集密钥尽可能缩小的主要原因,如果有的话,您应该检查群集密钥,然后询问您选择5字段群集密钥的原因,并且该选择是否会导致碎片化?
使用群集密钥的人工值(Identity)可能会更好,并使用唯一的NC索引来强制使用5字段聚类密钥的唯一性。
答案 1 :(得分:4)
聚集索引不需要包含。包括在索引树的最低级别存储额外数据的方法。此是聚簇索引中的数据。所以你不需要重叠索引
但是,如果您担心内存占用,则需要缩小表格。有了50k行,我会考虑从-32768开始的smallint代理键。然后,删除每个NC索引中C键的开销。这意味着您可以在问题中提到覆盖索引。
请注意,一旦您的执行计划被缓存并且数据位于缓存中,那么您的查询将来自内存。您的使用意味着它将在缓存中保留一段时间。缺少更新意味着您将无法获得统计驱动的重新编译。
但是,如果您的数据几乎是静态的,那么如果性能受到关注,为什么还要调用SQL Server呢?缓存它。根据我的缓存注释删除网络往返,这可能是您最大的开销。 我们将一些查找和缓存外包给我们的客户端以减少服务器负载(我们在峰值负载下大约20秒内有50k写入)
答案 2 :(得分:1)
这是有道理的 只是把额外的几个 列包含在“包含的列”中,但是 SQL Server不允许包含 聚集索引上的列
包含额外列是不可能的,因为聚簇索引已包含所有列。这就是索引被称为聚集的原因。
所以,我们有第二个索引 与...基本相同的字段 聚集索引,与另一个 列为“包含的列”。 但是,从我读过的内容来看,我 相信这可能是多余的?
是的,这可能是多余的。有一些罕见的例外,聚集索引不适合内存。
非聚集索引是否已成立 拥有群集中的列 在其中定义的索引?
可能:非聚集索引包含指向聚簇索引的指针。如果聚簇索引是唯一的,则此指针由所有聚簇索引字段组成。 (在大多数情况下,这些字段与主键对应。)
那么,有没有一种有效的设置方法 这些索引就这样全部了 该表的列可用 通过索引而不回头 到桌子?
在发布的示例中,看起来聚簇索引就足够了,并且您不需要任何其他索引来避免表查找。您可以通过运行查询并查找“密钥查找”或“清除查找”操作来验证这一点。
答案 3 :(得分:1)
我认为您需要更好地了解CLUSTERED和NONCLUSTERED索引。聚簇索引是平衡树(B树),其中每个节点包含索引的键列。通常,通常是最佳选项,一列是索引的关键列。每行的所有数据都存储在聚集索引的叶级(即底层)。这就是为什么你不能在聚簇索引中包含列;所有列都包含在定义中。
非聚集索引也是B树结构。每个节点都包含索引的键列。非聚集索引的叶级别包含任何包含的列。请注意,键列和包含列之间的区别在于键列值出现在索引的每个级别,而包含的列仅出现在叶级别。叶级别还包含聚集索引中的键列,用于将索引链接到表数据。
您在任何索引中包含的列越多,索引就越大。而且,这会降低性能。
因此,对于聚簇索引,您不需要将所有列,甚至许多列都包含在索引中作为键。数据已经是索引的一部分。