组合键 VS 主键 + 非唯一索引

Composite key VS primary key + not unique index

这是我的资料:

table content : cat_id product_id data1 data2 etc.
这些类别显然不是唯一的。 产品 ID 是唯一的。

2 queries : 1 -- SELECT * WHERE cat_id = :cat - must be as quick as possible 2 -- SELECT * WHERE product_id = :prodId In second select, I can add : AND cat_id = :cat

什么效率更高?

关于信息,我将在每个类别中有大约 20 种产品和很多类别(比如 3000)- 并且(因为它在 table 中是独一无二的)一种产品仅属于一个类别-在事实上,那不是真正的猫和产品,那是为了解释的简单;)

谢谢!

没有主键的数据库只穿了一半,根据您的说法 product_id 是主键的理想候选者,所以让我们选择它。主键将在

中使用
SELECT * WHERE product_id = :prodId

and cat_id = :cat_id 是否成为查询的一部分并不重要,除非您有数千个 cat_ids 与每个 product_id.

关联

然后在 cat_id 上选择一个索引。这将用于

SELECT * WHERE cat_id = :cat

如果数据的基数良好,这将非常快。这意味着 table 中的 cat_id 分布广泛。 cat_id 的索引将不会在第一个查询中使用。因此,您有两个不同的索引,并且可以预期两个查询都非常快。

[cat_id+product_id] != [product_id+cat_id] 开始,当涉及到索引时,如果您只有一个复合索引,那么一个或另一个都会很慢。

例如,假设我们现在在 (cat_id, product_id) 上有一个复合索引 以下查询无法使用此索引。

 SELECT * FROM tablename WHERE product_id = :prodId

但是这两个查询都可以使用 (cat_id, product_id) 索引

SELECT * FROM tablename WHERE cat_id = :cat_id and product_id = :prodId
SELECT * FROM tablename WHERE cat_id = :catId

综上所述。选择 1 和 2。但是,如果 cat_id 的数量很少,或者有很多 cat_id 与每个 product_id 关联,请选择 4,但要确保主键也已就位.

如果这些是您只有两个查询:

SELECT * FROM tablename WHERE cat_id = :cat_id and product_id = :prodId
SELECT * FROM tablename WHERE cat_id = :cat_id

你有其他方法可以确保product_idUNIQUE,那么你只需要 :

PRIMARY KEY(cat_id, product_id)

最适合两者 SELECTs

它比INDEX(cat_id)更好,因为(1)辅助键必须通过PK查找来完成它们的工作,并且(2)所有的猫行都是相邻的,因此效率更高。

如果product_id实际上是一个AUTO_INCREMENT,那么添加

INDEX(product_id)

不,你不需要说 UNIQUE(除非你倾向于故意插入重复的 product_ids)。 AI 唯一需要的是 id 在 some index 中排在第一位,这样它就可以在 mysqld 重新启动时执行相当于 SELECT max(id) 的操作。

无论 table 的大小如何,我的建议都适用。

WHERE 中子句的顺序重要。

JOINs 没有 要求 任何特别的东西。在 PRIMARY KEYJOIN 比在辅助键上效率稍高,这比在非索引列上效率高得多(但仍然可能)。