具有复合主键的表是否真的需要复合索引?

时间:2012-06-23 04:37:13

标签: sql

假设我们有一个表来存储用户喜欢的图片,其中包含复合主键对(UserId,PictureId)。书籍通常说在这种情况下你需要一个基于(UserId,PictureId)的复合索引,它通常出现在WHERE子句中(UserId = 103 AND PictureId = 1234)。但我认为dababase引擎应该足够聪明,可以分别根据两列使用两个单独的索引。只需获取每个索引的行号集,找到两个集合中存在的行号。这样,就不需要复合索引。

那么,实际上数据库引擎可以做到吗?

5 个答案:

答案 0 :(得分:2)

使用两个单独的单列索引没有任何好处;引擎最好不要进行表扫描。

使用索引的目的是使访问速度更快。如果引擎使用了两个索引,则必须从其中一个索引中排序至少一组数据,并合并两个索引的结果。这比仅读取一个复合索引要多得多,特别是因为复合索引允许仅索引扫描。

答案 1 :(得分:1)

大多数数据库引擎要求复合索引强制主键。因此,它是一个你将要拥有的“免费”指数 - 为什么要担心呢?

UserID,PictureID上添加第二个索引可能会有一些好处(如果索引在PictureID上)。对UserID的任何查询都可以使用复合索引,而仅使用PictureID的查询将无法执行此操作。

答案 2 :(得分:0)

我认为在您描述的用例中,复合索引不是必需的。如果您在一组给定的用户ID和一组给定的图片ID上进行查询,那将非常有用。但是你什么时候需要呢?您更有可能在给定日期范围内查询所有用户的图片,或按ID查找特定图片。这将建议一个复合用户ID +日期索引的索引结构,以及另一个图片ID 索引。

它总是取决于数据库中记录的分布以及最常运行的查询类型。

答案 3 :(得分:0)

您所描述的内容比使用复合索引要贵得多。

首先需要从第一个索引标识一组行,然后从第二个索引中识别出一组行,最后在两个行之间执行集合交集。

---更新---

请注意,这是您为每次 INSERT / UPDATE和每次外键检查支付的价格,而不仅仅是SELECT。

此外,可能涉及并发问题 - 取决于DBMS的实现方式,通过单个唯一复合索引强制执行唯一性可能需要更少/更简单的锁定,而不是通过两个非唯一的非复合索引强制执行唯一性。 p>

当然,如果您想要cluster您的表,主索引通常也将是聚类索引,并且无论如何都包含所有列,因此没有太多的目的可以从“排序”中留下任何内容“指数的一部分。

答案 4 :(得分:0)

PRIMARY KEY或UNIQUE约束是抽象,理论概念。

INDEX是生活在现实世界中的实用物理内容。

实际上,索引可用于强制执行PK或UNIQUE约束。但也可以使用其他技术(例如,对于小域:位图)