非标识列上的聚簇索引可加快批量插入?

tho*_*ulb 8 database sql-server identity-column clustered-index sql-server-2008

我的两个问题是:

  • 我可以使用聚簇索引来加速大表中的批量插入吗?
  • 如果我的IDENTITY列不再是聚集索引,我还能有效地使用外键关系吗?

详细说来,我有一个包含公司数据的几个非常大(在100-1000万行之间)的数据库.通常,在这样的表中存在大约20-40个公司的数据,每个公司都是由"CompanyIdentifier"(INT)标记的他们自己的"块".此外,每家公司都有大约20个部门,每个部门都有自己的"子块",标有"DepartmentIdentifier"(INT).

经常会发生从表中添加或删除整个"块"或"子块".我的第一个想法是在这些块上使用表分区,但由于我使用的是SQL Server 2008标准版,因此我无权使用它.尽管如此,我所拥有的大多数查询都是在"块"或"子块"上执行而不是在整个表格上执行.

我一直在努力为以下功能优化这些表:

  1. 在子块上运行的查询
  2. 作为整体在桌面上运行的"基准测试"查询
  3. 插入/删除大块数据.

对于1)和2)我没有遇到很多问题.我在关键字段上创建了几个索引(也包含有用的CompanyIdentifier和DepartmentIdentifier),查询运行正常.

但对于3)我一直在努力寻找一个好的解决方案.我的第一个策略是始终禁用索引,批量插入大块并重建索引.这在开始时非常快,但现在数据库中有很多公司,每次重建索引需要很长时间.

目前我的策略已经改为只是在插入时保持索引,因为现在这似乎更快.但我想进一步优化插入速度.

我似乎注意到通过添加在CompanyIdentifier + DepartmentIdentifier上定义的聚簇索引,将新的"块"加载到表中的速度更快.在我放弃这个策略以支持在IDENTITY列上添加聚簇索引之前,有几篇文章向我指出聚簇索引包含在所有其他索引中,因此聚簇索引应该尽可能小.但现在我正在考虑恢复这个旧策略来加速插入.我的问题,这是明智的,还是会在其他领域遇到性能打击?这真的会加速我的插入还是仅仅是我的想象力?

我也不确定在我的情况下是否确实需要IDENTITY列.我希望能够与其他表建立外键关系,但我是否也可以使用类似于CompanyIdentifier + DepartmentIdentifier + [uniquifier]方案的东西?或者它必须是一个表格,分散的IDENTITY数字?

非常感谢任何建议或解释.

tho*_*ulb 4

好吧,我已经对其进行了测试,并且在两个“块定义”列上放置聚集索引可以提高表的性能。

与我有聚集 IDENTITY 键的情况相比,插入块现在相对较快,并且与没有任何聚集索引时的速度差不多。删除块比使用或不使用聚集索引要快。

我认为我想要删除或插入的所有记录都保证集中在硬盘的某个部分,这使得表速度更快 - 对我来说这似乎是合乎逻辑的。


更新:经过一年的设计经验,我可以说,为了使这种方法发挥作用,有必要安排定期重建所有索引(我们每周进行一次)。否则,索引很快就会变得碎片化并且性能下降。尽管如此,我们正在迁移到带有分区表的新数据库设计,它基本上在各个方面都更好 - 除了企业服务器许可证成本,但我们现在已经忘记了它。至少我有。

  • 完全正确。查看[此答案](http://stackoverflow.com/questions/4310769/bulletin-board-database-optimization/4311900#4311900)末尾链接中的**仅数据模型**。CI 是为关系数据库设计的;注意按键。特别适合任何范围查询;数据分布(您所说的“分块”;插入负载分布;在页面和范围级别进行自我调整。您不应该做的一件事是在单调键上集群(与其设计相反)。之间还有更多的内容CI 和“硬盘”,但你会及时找到它们。 (2认同)