在具有稀有 updates/inserts 的 table 上实施复合索引

Implementing a composite index on a table with rare updates/inserts

我计划一个数据库架构来存储亚马逊产品属性和额外的 marketplace-specific 值(例如标题、艺术家、重量等)

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

以编程方式捕获并正确处理同一 ASIN 的 EAN 和 UPC 时的行为,因此请考虑所有 ASIN 的唯一性。我在 ASIN 上定义了一个 UNIQUE NONCLUSTERED CONSTRAINT 并将其与产品 table 关联为 one-to-many.

第二个 table 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) 列,它是虚拟的但实现了唯一性。

假设以下事实:

这里来三个问题:

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

根据您上面所说的,如果性能是个问题并且我认为索引是解决方案,我会在 ASINmid 上实施非聚集覆盖索引。像这样:

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

这样当你加入 ProductsData table 时,你可以利用索引来提高性能,因为中间是 'included',它将与索引和查询引擎将不需要更深入。

当然有很多前进的道路,但根据您的 post,这就是我倾向于的方向。希望对您有所帮助!

所以总结一下你的问题

  1. 我的意见是使用覆盖索引而不是复合索引。这是因为听起来您的 ProductsProductsData 之间的 link 是 ASIN,而 mid 正好适合。因此,没有必要在索引中将其与 ASIN 组合在一起......包括它在这里会很好用 - 在我看来它的设计目的。

  2. 如 1 中所述的非聚集索引,因为聚集索引 应该 是唯一的。此外,聚簇索引维护数据的顺序,因此如果您创建新产品并且其 ASIN 适合 table 中间的某个位置,这里会产生开销,因为 SQL 服务器将需要重新订购整个 table

  3. 我认为您可以去掉它...如果您不将该列用于任何用途,并且它只是一个您不会在任何查询中使用的虚拟值如果是我,我可能会放弃它。