mysql单个索引和联合索引的区别

联合索引和单个索引的区别:
如果我们创建了(area, age,salary)的复合索引,那么其实相当于创建了:
(area,age,salary),(area,age)、(area)三个索引,这被称为最佳左前缀
特性。因此我们在创建复合索引时应该将最常用作限制条件的列放在最左边,依次递减。
例:
select * from test where area='11'
select * from test where area='11' and age=1
select * from test where area='11' and age=1 and salary=2.0
以上有索引
select * from test where age=11
select * from test where age=1 and salary=2.0
以上无索引
-----------------------------------
如果在查询中需要匹配多个字段的条件,可以把这几个字段做个联合索引,效率要比在每个字段上加索引高多了
<think>我们正在讨论的是MySQL联合索引单个索引区别。根据用户提供的引用内容,我们可以总结出以下几点: 1. **联合索引(Composite Index)**: - 定义:针对多个列组合创建索引。 - 示例:`CREATE INDEX idx_user_order_status ON orders(user_id, order_status);` - 特点: - 遵循最前缀匹配原则:索引从最边的列开始匹配。例如,对于索引`(col1, col2, col3)`,查询条件包含`col1`、`col1col2`、`col1col2col3`时可以使用索引,但单独使用`col2`或`col3`则无法使用。 - 适用于多列查询条件:当查询条件同时涉及多个列时,联合索引可以高效地利用索引。 - 支持多列排序:当需要对多个列进行排序(如`ORDER BY col1, col2`)时,联合索引可以避免额外的排序操作。 - 减少索引数量:一个联合索引可以替代多个单列索引,从而减少存储空间占用,并降低维护成本。 2. **单个索引(Single-Column Index)**: - 定义:针对单个创建索引。 - 示例:`CREATE INDEX idx_user ON orders(user_id);` - 特点: - 只优化单列的查询:适用于查询条件只涉及该列的情况。 - 可以用于多个单列索引的合并:当查询条件使用`OR`连接多个列时,可以使用多个单列索引,通过索引合并(Index Merge)来优化查询(如`Using union`)。但索引合并可能不如联合索引高效,且索引过多会增加维护成本。 3. **区别总结**: - **适用列数**:单个索引只针对一列,联合索引针对多列。 - **查询优化**: - 单个索引只能优化单列的查询条件。 - 联合索引可以优化多列查询条件,但必须遵循最前缀原则。 - **存储空间**:联合索引通常比多个单列索引占用更少的空间(因为一个联合索引替代了多个单列索引)。 - **维护成本**:联合索引的维护成本低于多个单列索引(因为索引数量少)。 - **使用限制**:联合索引必须遵循最前缀原则,而单个索引无此限制。 4. **使用建议**: - 如果查询条件经常同时涉及多个列(尤其是AND连接),则联合索引更高效。 - 如果查询条件经常使用OR连接多个列,则可能需要多个单列索引(但需注意索引合并的性能索引数量)。 - 联合索引还可以避免排序操作(当排序顺序与索引顺序一致时)。 - 避免创建不必要的索引,因为索引会增加写操作(INSERT/UPDATE/DELETE)的开销。 5. **注意事项**: - 联合索引的列顺序非常重要,应根据查询频率选择性(Cardinality)来设计,通常将高选择性的列放在边。 - 当查询条件中只包含联合索引的非最列时,无法使用该索引(此时可能需要单独为该列创建索引)。 **示例对比**: 假设有一个订单表`orders`,包含`user_id`、`order_status``order_date`列。 - **场景1:同时查询`user_id``order_status`** - 联合索引`(user_id, order_status)`:高效,因为索引覆盖了两列。 - 两个单列索引(`user_id``order_status`):可能使用索引合并(如`Using intersect`),但效率通常低于联合索引。 - **场景2:只查询`order_status`** - 联合索引`(user_id, order_status)`:无法使用(因为不满足最前缀)。 - 单列索引`(order_status)`:高效。 - **场景3:查询`user_id`或`order_status`(OR条件)** - 联合索引:无法直接用于OR条件(除非使用索引合并,但联合索引本身不直接支持OR)。 - 两个单列索引:可能通过索引合并(`Using union`)来优化。 **总结选择策略**: - 优先使用联合索引的场景:多列AND查询、多列排序、减少索引数量。 - 考虑单列索引的场景:单列查询、OR条件查询、非最前缀的列查询。 通过以上分析,我们可以清晰地理解联合索引单个索引区别适用场景。</think>### MySQL 联合索引单个索引区别 #### 1. **定义与结构** - **单个索引(单列索引)** 针对单列创建索引,如 `CREATE INDEX idx_user ON orders(user_id);`。 数据结构:B+树中每个节点存储单列值及其行指针[^2][^3]。 - **联合索引复合索引)** 针对多列组合创建索引,如 `CREATE INDEX idx_user_status ON orders(user_id, order_status);`。 数据结构:B+树节点存储**多列值的组合**(例如:`(user_id, order_status)`),按索引定义时的列顺序排序[^1][^2]。 --- #### 2. **查询优化差异** | **场景** | **单个索引** | **联合索引** | |--------------------------|----------------------------------------|----------------------------------------| | **单列条件查询** | ✔️ 高效(如 `WHERE user_id=1`) | ✔️ 仅当该列是**最列**时高效(如 `WHERE user_id=1`)[^3] | | **多列条件查询** | ❌ 需多个索引合并(性能较低) | ✔️ 高效(如 `WHERE user_id=1 AND order_status='paid'`)[^1][^3] | | **非最列查询** | ✔️ 支持(如 `WHERE order_status='paid'`)| ❌ **无法使用索引**(如 `WHERE order_status='paid'`)[^3] | | **多列排序** | ❌ 需额外排序操作 | ✔️ 直接利用索引顺序(如 `ORDER BY user_id, order_status`)[^3] | | **OR 条件查询** | ✔️ 支持索引合并(`Using union`)[^5] | ❌ 联合索引失效,需回退到单列索引[^5] | --- #### 3. **存储与维护成本** | **属性** | **单个索引** | **联合索引** | |-------------------|------------------------------|------------------------------| | **存储空间** | 较小(每索引独立存储) | 较大(存储多列组合值)[^3] | | **索引数量** | 需多个索引覆盖多列 | **减少索引数量**(一索引覆盖多列)[^4] | | **写操作开销** | 较低(更新单列时只需维护一个索引) | 较高(更新任意索引列需维护整个联合索引)[^3] | --- #### 4. **核心原则:最前缀匹配** 联合索引必须遵循**最前缀规则**: - 索引 `(A, B, C)` 仅对以下查询有效: - `WHERE A=1` - `WHERE A=1 AND B=2` - `WHERE A=1 AND B=2 AND C=3` - **无效场景**: - `WHERE B=2`(跳过最列 `A`) - `WHERE B=2 AND C=3`[^2][^3] > **示例**: > ```sql > -- 有效:使用索引 (user_id, order_status) > SELECT * FROM orders WHERE user_id=1; > SELECT * FROM orders WHERE user_id=1 AND order_status='paid'; > > -- 无效:无法使用索引 > SELECT * FROM orders WHERE order_status='paid'; > ``` --- #### 5. **实践建议** 1. **优先选择联合索引**: 当查询频繁涉及**固定多列组合**(如 `WHERE A AND B`)或多列排序时[^3][^4]。 2. **谨慎设计列顺序**: 将**高选择性列(唯一值多)** 放在最侧(如 `user_id` 比 `status` 更适合作为最列)[^2]。 3. **单列索引适用场景**: - 列单独查询频率高 - OR 条件查询较多[^5] - 非最列的查询需求 4. **避免过度索引**: 联合索引虽减少索引数量,但每个索引会增加写操作开销[^3][^4]。 > **性能对比示例**: > ```sql > -- 方案1:两个单列索引(user_id order_status) > EXPLAIN SELECT * FROM orders > WHERE user_id=1 AND order_status='paid'; > -- 可能触发 Index Merge(Using intersect),效率较低 > > -- 方案2:联合索引 (user_id, order_status) > EXPLAIN SELECT * FROM orders > WHERE user_id=1 AND order_status='paid'; > -- 直接使用联合索引,效率更高[^1][^3] > ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值