在具有罕见更新/插入的表上实现复合索引

时间:2015-09-24 17:00:27

标签: sql-server database-schema composite-primary-key clustered-index composite-index

我计划一个数据库架构来存储亚马逊产品属性和额外的市场特定值(例如标题,艺术家,重量等)。

到目前为止,还有一个带有GTIN varchar(13) (PK)列的产品表。在我的特定情况下,GTIN可以是EAN / UPC / ISBN标识符。产品中还有一个ASIN char(10)列,用于将GTIN与ASIN相关联。

当同一个ASIN存在EAN和UPC时的行为以编程方式捕获并正确处理,因此请考虑所有ASIN都是唯一的。我在UNIQUE NONCLUSTERED CONSTRAINT上定义了ASIN,并将其与产品表关联为一对多

第二个表 ProductsData 定义ASIN char(10) (FK)mid tinyint(市场ID)。所有ASIN与相应的市场ID一起存储:

rowid    ASIN          mid
1        B0002DB5GS    1
2        B0002DB5GS    44
3        B0002DB5GS    39
4        B0002Y4SYS    1
5        B0002Y4SYS    44
6        B0002Y4SYS    39

正如您所注意到的,还有一个rowid int IDENTITY(1,1)列,它是虚拟的,但实现了唯一性。

承担以下事实:

  • 非常罕见的更新
  • 相对罕见的插入(每个添加的产品在事务中创建3条记录)
  • 无删除
  • 在ASIN列上进行密集选择
  • rowid是一个假人,只能确保唯一性。

这里有三个问题:

  1. 是否值得在ASINmid上制作复合索引
  2. 如果是,则是群集还是非群集?
  3. 我可以在rowid上删除聚集索引,因为我真的不需要它吗?

1 个答案:

答案 0 :(得分:1)

根据您的说法,如果性能是一个问题,我觉得索引是解决方案,我会在ASINmid上实现非聚集覆盖索引。像这样:

CREATE NONCLUSTERED INDEX IX_ASIN_COVERING_mid ON ProductsData (ASIN) INCLUDE (mid)

这种方式当你加入ProductsData表时,你可以利用索引来提高性能,因为中间包含了#,它将与索引一起存储,查询引擎将不需要深入了解。

当然有许多前进的道路,但根据你的帖子,这是我倾向于的。希望它有所帮助!

所以总结一下你的问题

  1. 我的意见是使用覆盖索引而不是复合索引。这是因为听起来ProductsProductsData之间的链接是ASIN,而mid恰好是骑行。因此,在索引中将它与ASIN组合起来是没有必要的......包括它在这里会很好用 - 在我看来它的设计类型。

  2. 非群集,如1所述,因为群集索引应该是唯一的。此外,聚簇索引维护数据的排序,因此如果您创建一个新产品并且其ASIN适合表中间的某个位置,则此处存在开销,因为SQL Server将需要重新排序整个表

  3. 我认为你可以摆脱它...如果你没有使用该列的任何东西,它只是一个你在任何查询中都不会使用的虚拟值然后,如果是我,我可能会放弃它。