具有nvarchar主键的表上的PK索引碎片

时间:2013-10-25 14:18:20

标签: sql sql-server indexing

由于最近我们一直在使用的一些数据库问题,我一直在研究索引的状态并尝试减少碎片。

该应用程序有几个名称表,如BoysNames和GirlsNames,我们用它来设置我们创建的User对象的属性。这里显而易见的属性是性别。这些表可以有几百到几万行。

这些表的结构如下:

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

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

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

  1. 第一个是当我从表中选择每个名字并将其存储时 用于对进入系统的新用户使用的内存,所以我可以这样做:if (boysNames.Contains(user.Name)){user.Gender =“M”};这发生得很好 常。
  2. 第二个是当我在列表中添加新名称时,我会检查 存在一个名称,如果它不存在,我加上它。有时候是这样的 很少。
  3. 所以我需要知道的是:

    这种高水平的碎片是否会导致我出现问题?如果在重新组织/重建后将索引碎片设置为50%,我怎样才能将索引碎片减少到0%?

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

1 个答案:

答案 0 :(得分:0)

如果索引页面驻留在内存中,可能只有少量行,则碎片无关紧要。您可以使用count(*)查询对此进行基准测试。从第二次执行开始,您应该看到内存速度。如果您现在比较100%和0%碎片表的结果,您应该看不出差异。

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

IDENTITY字段上进行群集会删除聚簇索引的碎片,但您可能需要Name上的索引再次碎片化。如果您根本不需要任何索引,请将其设置为堆表并完成它。不过,我建议非常反对。