组合键 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
什么效率更高?
- 1 - 在 cat_id 上的索引 (不唯一)(适合 select 1)
- 2 - product_id 上的主键(唯一 -> 非常适合 select 2)
- 3 - 索引 (不唯一)cat_id 上的 + product_id 上的 PK(分别适用于 1 和 2)
- 4 - 具有复合 [cat_id+product_id] 的唯一约束(适用于 1 和 2)
- 5 - 与 4 相同,但将复合定义为 PK
- 6 - 复合(4 或 5)+ 单 index/PK
关于信息,我将在每个类别中有大约 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_id
是UNIQUE
,那么你只需要 :
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 KEY
上 JOIN
比在辅助键上效率稍高,这比在非索引列上效率高得多(但仍然可能)。
这是我的资料:
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
什么效率更高?
- 1 - 在 cat_id 上的索引 (不唯一)(适合 select 1)
- 2 - product_id 上的主键(唯一 -> 非常适合 select 2)
- 3 - 索引 (不唯一)cat_id 上的 + product_id 上的 PK(分别适用于 1 和 2)
- 4 - 具有复合 [cat_id+product_id] 的唯一约束(适用于 1 和 2)
- 5 - 与 4 相同,但将复合定义为 PK
- 6 - 复合(4 或 5)+ 单 index/PK
关于信息,我将在每个类别中有大约 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_id
是UNIQUE
,那么你只需要 :
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 KEY
上 JOIN
比在辅助键上效率稍高,这比在非索引列上效率高得多(但仍然可能)。