【问题标题】:Clustered and nonclustered index large data insert聚集和非聚集索引大数据插入
【发布时间】:2013-06-04 22:08:01
【问题描述】:

我在 5 个键(列)上有一个聚集索引。我在 2 列上有一个非聚集索引。因为我在一次运行中插入了 2-3 百万行,所以我将 2 列非聚集索引更改为聚集索引,并将 5 列聚集索引更改为 5 列非聚集索引。我的问题。

  1. 在创建集群索引时(基本上删除并重新创建索引为clustered),我不需要include(任何列),因为它是集群的?

  2. 将较少的列索引切换为聚集索引并将大列的聚集索引更改为非聚集索引通常是否正确?换句话说,聚簇索引应该简单而小?

  3. 如果我切换这两个索引会不会出现性能问题?

【问题讨论】:

    标签: sql sql-server indexing sql-server-2012


    【解决方案1】:

    除非它是链接表,否则您通常在 1 列上有聚集索引。一般建议是为聚集索引列选择尽可能小的类型(肯定符合您的要求)。拥有许多列不仅会增加大小(每个非聚集索引存储聚集索引的值[包括聚集索引]!),而且还会大大增加外部碎片和降低性能的机会,即使是inserts。因此,我对您的问题的回答。

    1. 没错,聚集索引是一张表,不需要包含任何列
    2. 是的,绝对是
    3. 如果您问的是切换本身的性能或较小(或更少列)聚集索引的性能影响,我不确定该怎么办,所以我会尝试回答这两个问题。
      • 自行切换。当您将聚集索引切换到非聚集索引时,我相信它应该不会很昂贵(我认为引擎实际上不会对块和范围进行洗牌以形成堆)。肯定 IAM 必须改变,这需要时间。将非聚集索引更改为聚集索引涉及更多活动。除了根据聚集索引键移动数据外,SQLServer 还必须更新所有非聚集索引。
      • 进一步的影响(相当大的话题,我给出了一个非常简短的答案)...较小的聚集索引意味着存储所有其他索引所需的空间更少,这反过来意味着更快地访问数据并减少引擎的资源消耗。

    更新我意识到(感谢 Aaron Bertrand 指出这一点)我对将聚集索引包含在非聚集索引中做了相当模糊的陈述。绝对正确,每个非聚集索引都包含指向行的行定位器。当表被聚集时,行定位器是聚集索引键。有关聚集索引的更多信息:[1][2]

    【讨论】:

    • +1 你暗示了这一点,但更明确地说,集群键包含在所有非聚集索引中......所以它越宽,所有非聚集索引越宽也是。
    • @Aaron Bertrand:谢谢,我会大胆地吸引更多关注。
    • 是的,我现在在第 1 段中看到了,但不知何故我错过了,以为只是在最后一个项目符号中模糊地引用了它。
    • 好吧,我不是想学究气,但我不认为includes clustered index 是完全正确的。这可能意味着整个表都包含在索引中,而实际上它只是集群键。
    • @Aaron Bertrand:再次感谢(+),我相信我现在已经尽可能清楚地表达了...
    猜你喜欢
    • 2013-08-07
    • 2016-01-05
    • 2021-01-14
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 2013-03-22
    • 2014-08-27
    相关资源
    最近更新 更多