每个用户表都应该具有聚簇索引吗?

Sre*_*har 24 sql-server indexing sqlperformance sql-server-2008 sql-server-2008-r2

最近我在数据库中找到了几个没有定义聚簇索引的表.但是定义了非聚集索引,因此它们处于HEAP状态.

在分析中,我发现select语句对非聚集索引中定义的列使用过滤器.

这些表上没有聚簇索引会影响性能吗?

Tim*_*ner 49

很难比SQL Server MVP Brad McGehee更简洁地说明这一点:

根据经验,每个表都应该有一个聚簇索引.通常,但并非总是如此,聚簇索引应该在单调增加的列上 - 例如标识列,或者值增加的其他列 - 并且是唯一的.在许多情况下,主键是聚簇索引的理想列.

BOL回应了这种情绪:

除了少数例外,每个表都应该有一个聚簇索引.

这样做的原因很多,主要是基于聚簇索引在物理上对存储中的数据进行排序的事实.

  • 如果聚簇索引在单个列上单调增加,则在存储设备上按顺序进行插入,并且不会发生页面拆分.

  • 当索引值是唯一的时,聚簇索引对于查找特定行是有效的,例如基于主键选择行的常见模式.

  • 聚簇索引经常允许高效的查询的列上是经常搜索的值的范围(between,>等).

  • 群集可以加速查询,其中数据通常按特定列排序.

  • 可以根据需要重建或重组聚簇索引以控制表碎片.

  • 这些好处甚至可以应用于视图.

您可能不希望拥有聚集索引:

  • 频繁更改数据的列,因为SQL Server必须在物理上重新排序存储中的数据.

  • 已被其他索引覆盖的列.

  • 宽键,因为聚簇索引也用于非聚集索引查找.

  • GUID列虽然大于标识并且也是有效的随机值(不太可能被排序),但newsequentialid()可用于帮助减轻插入期间的物理重新排序.

  • 使用(没有聚簇索引的表)的一个罕见原因是,数据总是通过非聚簇索引访问,并且已知RID(SQL Server内部行标识符)小于聚簇索引键.

由于这些和其他注意事项(例如特定的应用程序工作负载),您应该仔细选择聚簇索引以获得查询的最大好处.

另请注意,在SQL Server中的表上创建主键时,它将默认创建唯一的聚簇索引(如果它还没有).这意味着如果您发现一个表没有聚集索引,但确实有一个主键(因为所有表都应该),开发人员之前已决定以这种方式创建它.您可能希望有一个令人信服的理由来改变它(其中有很多,正如我们所见).添加,更改或删除聚簇索引需要重写整个表和任何非聚簇索引,因此这可能需要一些大型表.

  • 聚簇索引以这种方式工作良好,因为保证下一个较高或较低的键控行在存储中彼此物理上相邻.因此,一旦找到第一个值,就不必搜索剩余的行; 你已经找到了它们. (4认同)
  • 它们不能保证与存储物理相邻.它们只保证在逻辑上相邻.这就是您需要重新组织或重建索引的原因. (2认同)
  • 有趣的文章在这里推动堆:http://use-the-index-luke.com/blog/2014-01/unreasonable-defaults-primary-key-clustering-key (2认同)