我的两个问题是:
- 我可以使用聚集索引来加速大表中的批量插入吗?
- 如果我的 IDENTITY 列不再是聚集索引,我还能有效地使用外键关系吗?
详细地说,我有一个数据库,其中包含几个非常大的(100-10 亿行之间)表,其中包含公司数据。通常在这样的表中有大约 20 到 40 家公司的数据,每家公司都是由“CompanyIdentifier”(INT)标记的自己的“块”。此外,每家公司都有大约 20 个部门,每个部门都有自己的“子块”,用“部门标识符”(INT) 标记。
经常会从表中添加或删除整个“块”或“子块”。我的第一个想法是在这些块上使用表分区,但由于我使用的是 SQL Server 2008 标准版,因此我无权使用它。尽管如此,我的大多数查询都是在“块”或“子块”上执行的,而不是在整个表上执行的。
我一直在努力针对以下功能优化这些表:
- 在子块上运行的查询
- 在整个表上运行的“基准测试”查询
- 插入/删除大块数据。
对于1)和2)我没有遇到很多问题。我已经在关键字段上创建了几个索引(还包含有用的 CompanyIdentifier 和 DepartmentIdentifier)并且查询运行良好。
但是对于 3) 我一直在努力寻找一个好的解决方案。我的第一个策略是始终禁用索引,批量插入一大块并重建索引。一开始这个速度很快,但是现在数据库里有很多公司,每次重建索引都需要很长时间。
目前,我的策略已更改为仅在插入时保持索引打开,因为现在这似乎更快。但我想进一步优化插入速度。
我似乎注意到通过添加在 CompanyIdentifier + DepartmentIdentifier 上定义的聚集索引,将新“块”加载到表中更快。在我放弃此策略以支持在 IDENTITY 列上添加聚集索引之前,正如几篇文章向我指出的那样,聚集索引包含在所有其他索引中,因此聚集索引应该尽可能小。但现在我正在考虑恢复这种旧策略以加快插入速度。我的问题是,这是否明智,或者我会在其他领域遭受性能打击?这真的会加快我的插入速度还是只是我的想象?
我也不确定在我的情况下是否真的需要一个 IDENTITY 列。我希望能够与其他表建立外键关系,但我也可以为此使用 CompanyIdentifier+DepartmentIdentifier+[uniquifier] 方案吗?或者它必须是一个表范围的、碎片化的 IDENTITY 编号?
非常感谢任何建议或解释。