最近,我在数据库中发现了几个没有定义聚集索引的表。
但定义了非聚集索引,因此它们位于 HEAP 上。
经过分析,我发现 select 语句对非聚集索引中定义的列使用过滤器。
这些表上没有聚集索引会影响性能吗?
很难比 SQL Server MVP 更简洁地表述这一点布拉德·麦吉 https://www.sql-server-performance.com/author/bradmcgehee/:
根据经验,每个表都应该有一个聚集索引。 https://www.sql-server-performance.com/clustered-indexes/一般来说,但并非总是如此,聚集索引应该位于单调增加的列上(例如标识列或值不断增加的其他列)并且是唯一的。在许多情况下,主键是聚集索引的理想列。
BOL https://msdn.microsoft.com/en-us/library/ms186342.aspx呼应了这种情绪:
除了少数例外,每个表都应该有一个聚集索引。
这样做的原因有很多,主要基于以下事实:聚集索引对存储中的数据进行物理排序.
-
如果您的聚集索引位于单调增加的单个列上,则插入会按顺序在存储设备上发生,并且不会发生页面拆分。
-
当索引值唯一时,聚集索引可以有效地查找特定行,例如基于主键选择行的常见模式。
-
聚集索引often https://www.sqlinthewild.co.za/index.php/2011/02/01/is-a-clustered-index-best-for-range-queries/允许对经常搜索值范围的列进行高效查询(between
, >
, etc.).
-
集群可以加快数据通常按特定列排序的查询速度。
-
可以根据需要重建或重新组织聚集索引以控制表碎片。
-
这些好处甚至可以应用于视图 https://msdn.microsoft.com/en-us/library/ms191432.aspx.
您可能不希望在以下位置上有聚集索引:
-
数据频繁更改的列,因为 SQL Server 必须对存储中的数据进行物理重新排序。
-
已被其他索引覆盖的列。
-
宽键,因为聚集索引也用于非聚集索引查找。
-
GUID 列,比身份大,也是有效的随机值(不太可能进行排序)newsequentialid() https://msdn.microsoft.com/en-us/library/ms189786.aspx可用于帮助减少插入期间的物理重新排序。
-
使用的罕见原因heap https://msdn.microsoft.com/en-us/library/hh213609(没有聚集索引的表)是指数据始终通过非聚集索引访问,并且 RID(SQL Server 内部行标识符)已知小于聚集索引键。
由于这些和其他考虑因素(例如您的特定应用程序工作负载),您应该仔细选择聚集索引,以获得查询的最大利益。
另请注意当您在 SQL Server 中的表上创建主键时,默认情况下它将创建唯一的聚集索引(如果还没有的话)。这意味着,如果您发现一个表没有聚集索引,但有主键(所有表都应该如此),则开发人员之前已决定以这种方式创建它。您可能想要有一个令人信服的理由来改变这一点(正如我们所见,有很多理由)。添加、更改或删除聚集索引需要重写整个表以及任何非聚集索引,因此在大型表上这可能需要一些时间。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)