【问题标题】:PK Index Fragmentation on tables with nvarchar primary keys具有 nvarchar 主键的表上的 PK 索引碎片
【发布时间】:2013-10-25 14:18:20
【问题描述】:

由于我们最近遇到的一些数据库问题,我一直在查看索引的状态并尝试减少碎片。

该应用程序有几个名称表,例如 BoysNames 和 GirlsNames,我们使用它们来设置我们创建的 User 对象的属性。这里最明显的属性是 Gender。这些表可以有几百到 10,000 行。

这些表格的结构如下:

Name - nvarchar(50) - PK & Clustered Index
DateCreated - datetime

当我告诉 Sql Server 重新组织或重建我所有表上的索引时,大多数表碎片下降到 0%,但其中一些 Name 表立即碎片化了 50%。

我只在 2 个地方访问这些表:

  1. 第一个是当我从表中选择每个名称并将其存储在 内存来对付进入系统的新用户,所以我可以做这样的事情:如果 (boysNames.Contains(user.Name)) {user.Gender = "M"};这发生得很 经常。
  2. 第二个是当我向列表中添加新名称时,我会检查 名称的存在,如果它不存在,我添加它。有时候是这样的 很少。

所以我需要知道的是:

这种高度的碎片化会给我带来麻烦吗?在重组/重建后直接将索引碎片设置为 50% 时,如何将索引碎片减少到 0%?

我应该使用 int 作为主键并在 Name 上放置索引,还是 nvarchar 是主键的正确选择?

【问题讨论】:

  • 您可以在名称上保留 PK,但在自增整数上创建聚集索引
  • 我认为因为这些表将被从 A-Z 搜索,所以最好在名称上使用聚簇索引,因为它会加快速度。还是现在它是这样运作的?
  • 它会使您的表格碎片化,因为名称不是按字母顺序插入的。无论如何,PK 都会在名称上创建一个唯一索引
  • 顺便说一句,如果你的表没有增长那么多,那还不错,但是在 c 的开头有一个好的设计总是更好
  • 页面中的索引有多大?如果它们小于 1000 页,则您应该期望它们始终是零散的(您不必担心)。对于非常大的表也是如此。

标签: sql sql-server indexing


【解决方案1】:

如果索引页常驻在内存中(很可能只有那几行),那么碎片就无关紧要了。您可以使用count(*) 查询对其进行基准测试。从第二次执行开始,您应该会看到内存中的速度。如果您现在比较 100% 和 0% 碎片表的结果,您应该看不出有什么区别。

我认为你没有问题。如果您坚持,您可以将填充因子设置为低于 100,以便在随机位置插入行时有空间容纳新行。从 90 开始,然后以 5 为增量降低,直到您对出现的速率碎片感到满意为止。

IDENTITY 字段上进行聚类会消除聚集索引的碎片,但您可能需要Name 上的索引,该索引再次碎片。如果您根本不需要任何索引,请将其设为堆表并使用它。不过,我强烈反对这样做。

【讨论】:

    猜你喜欢
    • 2015-11-06
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-02
    • 1970-01-01
    相关资源
    最近更新 更多