在具有稀有 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)
列,它是虚拟的但实现了唯一性。
假设以下事实:
- 非常罕见的更新
- 相对罕见的插入(每个添加的产品在交易中创建 3 条记录)
- 没有删除
- 对 ASIN 列进行密集选择
rowid
是一个确保唯一性的虚拟变量。
这里来三个问题:
- 是否值得在
ASIN
和 mid
上制作一个 复合索引 ?
- 如果是,集群或non-clustered?
- 我可以删除
rowid
上的 聚集索引 因为我真的不需要它吗?
根据您上面所说的,如果性能是个问题并且我认为索引是解决方案,我会在 ASIN
和 mid
上实施非聚集覆盖索引。像这样:
CREATE NONCLUSTERED INDEX IX_ASIN_COVERING_mid ON ProductsData (ASIN) INCLUDE (mid)
这样当你加入 ProductsData
table 时,你可以利用索引来提高性能,因为中间是 'included',它将与索引和查询引擎将不需要更深入。
当然有很多前进的道路,但根据您的 post,这就是我倾向于的方向。希望对您有所帮助!
所以总结一下你的问题
我的意见是使用覆盖索引而不是复合索引。这是因为听起来您的 Products
和 ProductsData
之间的 link 是 ASIN,而 mid 正好适合。因此,没有必要在索引中将其与 ASIN 组合在一起......包括它在这里会很好用 - 在我看来它的设计目的。
如 1 中所述的非聚集索引,因为聚集索引 应该 是唯一的。此外,聚簇索引维护数据的顺序,因此如果您创建新产品并且其 ASIN 适合 table 中间的某个位置,这里会产生开销,因为 SQL 服务器将需要重新订购整个 table
我认为您可以去掉它...如果您不将该列用于任何用途,并且它只是一个您不会在任何查询中使用的虚拟值如果是我,我可能会放弃它。
我计划一个数据库架构来存储亚马逊产品属性和额外的 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)
列,它是虚拟的但实现了唯一性。
假设以下事实:
- 非常罕见的更新
- 相对罕见的插入(每个添加的产品在交易中创建 3 条记录)
- 没有删除
- 对 ASIN 列进行密集选择
rowid
是一个确保唯一性的虚拟变量。
这里来三个问题:
- 是否值得在
ASIN
和mid
上制作一个 复合索引 ? - 如果是,集群或non-clustered?
- 我可以删除
rowid
上的 聚集索引 因为我真的不需要它吗?
根据您上面所说的,如果性能是个问题并且我认为索引是解决方案,我会在 ASIN
和 mid
上实施非聚集覆盖索引。像这样:
CREATE NONCLUSTERED INDEX IX_ASIN_COVERING_mid ON ProductsData (ASIN) INCLUDE (mid)
这样当你加入 ProductsData
table 时,你可以利用索引来提高性能,因为中间是 'included',它将与索引和查询引擎将不需要更深入。
当然有很多前进的道路,但根据您的 post,这就是我倾向于的方向。希望对您有所帮助!
所以总结一下你的问题
我的意见是使用覆盖索引而不是复合索引。这是因为听起来您的
Products
和ProductsData
之间的 link 是 ASIN,而 mid 正好适合。因此,没有必要在索引中将其与 ASIN 组合在一起......包括它在这里会很好用 - 在我看来它的设计目的。如 1 中所述的非聚集索引,因为聚集索引 应该 是唯一的。此外,聚簇索引维护数据的顺序,因此如果您创建新产品并且其 ASIN 适合 table 中间的某个位置,这里会产生开销,因为 SQL 服务器将需要重新订购整个 table
我认为您可以去掉它...如果您不将该列用于任何用途,并且它只是一个您不会在任何查询中使用的虚拟值如果是我,我可能会放弃它。