多列上的多个索引
Multiple indexes on multiple columns
假设我有一个大小合适的 MySQL table(我们称之为 departments
),其中有一堆像这样聚集在一起的列:
部门Table:
| id | ds_settings | ds_reports | sales_settings | sales_reports | eng_settings | eng_reports | ops_settings | ops_reports | queryable_id | queryable_type |
|----|-------------|------------|----------------|---------------|--------------|-------------|--------------|-------------|--------------|----------------|
就列而言,我们有 "settings" 和 "reports"。当查询此 table 时,它通常只查找给定 "queryable" id 和类型的所有设置或报告。
所以对此 table 的大多数查询最终会看起来像这样:
SELECT ds_settings, sales_settings, eng_settings, ops_settings
FROM departments
where queryable_id = 1
AND queryable_type = "User"
为什么问题是,索引这个 table 的正确方法是什么?包含包含所有 "settings" 和所有 "reports" 的索引是否具有设计意义,例如:
UNIQUE KEY `index_on_settings` (`queryable_id`,`queryable_type`,
`ds_settings`,`sales_settings`,`eng_settings`)
...或者这是对复合索引应该如何工作的误解?
考虑键时,应按顺序将以下元素用于索引。字段用于:
- 加入
- 哪里(常量字段)
- 其中(范围字段)
- 排序
- 分组依据
在这种情况下,您将通过常量查找值按两个字段进行搜索,因此请将它们保留为索引。无需施加唯一约束。
虽然您可以将检索到的字段包含在索引中,但它的缺点是会增加索引中条目的大小并使搜索索引的速度变慢。如果您在一个非常常见的查询中有一个小字段,那么这可能是值得的,但是如果您的情况似乎还为时过早。
所以:
ALTER TABLE departments ADD KEY index_on_settings (queryable_id, queryable_type)
我假设 id
是主键。
推荐通读https://dev.mysql.com/doc/refman/8.0/en/mysql-indexes.html. There is also a good presentation here on index usage https://github.com/jynus/query-optimization。
两点回答你的问题:
- 索引将建立在
WHERE
子句中的属性上,而不是建立在 SELECT
子句中的属性上。
- 您应该在所需的最少属性上构建索引,因为如果您包含的属性比需要的多,那么您的插入和更新也必须更新索引,从而导致它们变慢。
假设我有一个大小合适的 MySQL table(我们称之为 departments
),其中有一堆像这样聚集在一起的列:
部门Table:
| id | ds_settings | ds_reports | sales_settings | sales_reports | eng_settings | eng_reports | ops_settings | ops_reports | queryable_id | queryable_type |
|----|-------------|------------|----------------|---------------|--------------|-------------|--------------|-------------|--------------|----------------|
就列而言,我们有 "settings" 和 "reports"。当查询此 table 时,它通常只查找给定 "queryable" id 和类型的所有设置或报告。
所以对此 table 的大多数查询最终会看起来像这样:
SELECT ds_settings, sales_settings, eng_settings, ops_settings
FROM departments
where queryable_id = 1
AND queryable_type = "User"
为什么问题是,索引这个 table 的正确方法是什么?包含包含所有 "settings" 和所有 "reports" 的索引是否具有设计意义,例如:
UNIQUE KEY `index_on_settings` (`queryable_id`,`queryable_type`,
`ds_settings`,`sales_settings`,`eng_settings`)
...或者这是对复合索引应该如何工作的误解?
考虑键时,应按顺序将以下元素用于索引。字段用于:
- 加入
- 哪里(常量字段)
- 其中(范围字段)
- 排序
- 分组依据
在这种情况下,您将通过常量查找值按两个字段进行搜索,因此请将它们保留为索引。无需施加唯一约束。
虽然您可以将检索到的字段包含在索引中,但它的缺点是会增加索引中条目的大小并使搜索索引的速度变慢。如果您在一个非常常见的查询中有一个小字段,那么这可能是值得的,但是如果您的情况似乎还为时过早。
所以:
ALTER TABLE departments ADD KEY index_on_settings (queryable_id, queryable_type)
我假设 id
是主键。
推荐通读https://dev.mysql.com/doc/refman/8.0/en/mysql-indexes.html. There is also a good presentation here on index usage https://github.com/jynus/query-optimization。
两点回答你的问题:
- 索引将建立在
WHERE
子句中的属性上,而不是建立在SELECT
子句中的属性上。 - 您应该在所需的最少属性上构建索引,因为如果您包含的属性比需要的多,那么您的插入和更新也必须更新索引,从而导致它们变慢。