MySQL(56)什么是复合索引?

复合索引(Composite Index),也称为多列索引,是在数据库表的多列上创建的索引。它可以提高涉及多个列的查询性能,通过组合多个列的值来索引数据。复合索引特别适用于需要同时过滤多列的查询。

复合索引的优点

  1. 提高多列查询的性能:复合索引能够优化涉及多个列的查询。
  2. 支持多种查询模式:可以支持前缀列的多种组合查询。
  3. 减少索引的数量:相比于为每一列创建单独的索引,复合索引可以减少索引的数量和维护开销。

1. 示例表结构

假设有一个名为 employees 的表,用于存储员工信息:

sql 复制代码
CREATE TABLE employees (
    emp_id INT AUTO_INCREMENT PRIMARY KEY,
    emp_name VARCHAR(100),
    department_id INT,
    salary DECIMAL(10, 2),
    hire_date DATE
);

2. 创建复合索引

假设我们经常需要按 department_idsalary 查询员工数据:

sql 复制代码
SELECT emp_name, salary FROM employees WHERE department_id = 2 AND salary > 50000;

可以为 department_idsalary 列创建复合索引:

sql 复制代码
CREATE INDEX idx_dept_salary ON employees(department_id, salary);

3. 使用 EXPLAIN 验证复合索引

使用 EXPLAIN 分析查询的执行计划,验证是否使用了复合索引:

sql 复制代码
EXPLAIN SELECT emp_name, salary FROM employees WHERE department_id = 2 AND salary > 50000;

假设 EXPLAIN 的输出如下:

plaintext 复制代码
+----+-------------+----------+------------+-------+----------------+-------------+---------+------+------+----------+-------------+
| id | select_type | table    | partitions | type  | possible_keys  | key         | key_len | ref  | rows | filtered | Extra       |
+----+-------------+----------+------------+-------+----------------+-------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | employees| NULL       | ref   | idx_dept_salary| idx_dept_salary| 8   | const| 100  |   100.00 | Using where |
+----+-------------+----------+------------+-------+----------------+-------------+---------+------+------+----------+-------------+

key 列中显示 idx_dept_salary 表示查询使用了复合索引。

4. 复合索引的使用规则

复合索引的顺序非常重要,因为查询优化器会根据索引列的顺序来利用索引。我们需要理解以下几种情况:

示例查询1:完全匹配索引的前缀

查询使用索引的前缀列:

sql 复制代码
SELECT emp_name, salary FROM employees WHERE department_id = 2;

这查询只使用了复合索引的第一个列 department_id,仍然可以利用复合索引。

示例查询2:匹配索引的所有列

查询使用了所有的索引列:

sql 复制代码
SELECT emp_name, salary FROM employees WHERE department_id = 2 AND salary > 50000;

这种查询可以完全利用复合索引。

示例查询3:不匹配索引的前缀

查询不使用索引的前缀列:

sql 复制代码
SELECT emp_name, salary FROM employees WHERE salary > 50000;

这种查询无法利用复合索引,因为 department_id 是索引的前缀,但查询中并未使用。

5. 复合索引的局限性

尽管复合索引可以显著提高查询性能,但它们也有一些局限性:

  1. 索引顺序重要:复合索引的列顺序会影响查询的性能,选择不当可能无法充分利用索引。
  2. 增加写操作的开销:插入、更新、删除操作需要维护更多的索引,增加了写操作的开销。
  3. 占用更多存储空间:复合索引会占用更多的磁盘空间。

6. 复合索引的最佳实践

  1. 合理选择列顺序:将选择性高的列放在复合索引的前面,以最大化查询性能。
  2. 考虑查询模式:根据常见的查询模式设计复合索引,以确保查询能够利用索引。
  3. 监控和优化 :使用 EXPLAIN 分析查询性能,确保查询优化器选择适当的索引。

7. 复合索引的高级示例

假设我们有一个更复杂的查询需求,涉及多个列的组合:

sql 复制代码
SELECT emp_name, salary FROM employees WHERE department_id = 2 AND salary > 50000 AND hire_date > '2023-01-01';

可以为 department_idsalaryhire_date 列创建复合索引:

sql 复制代码
CREATE INDEX idx_dept_salary_date ON employees(department_id, salary, hire_date);

使用 EXPLAIN 分析这个查询的执行计划:

sql 复制代码
EXPLAIN SELECT emp_name, salary FROM employees WHERE department_id = 2 AND salary > 50000 AND hire_date > '2023-01-01';

假设 EXPLAIN 的输出如下:

plaintext 复制代码
+----+-------------+----------+------------+-------+-------------------+-------------------+---------+-------+------+----------+-------------+
| id | select_type | table    | partitions | type  | possible_keys     | key               | key_len | ref   | rows | filtered | Extra       |
+----+-------------+----------+------------+-------+-------------------+-------------------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | employees| NULL       | ref   | idx_dept_salary_date | idx_dept_salary_date | 12    | const | 100  |   100.00 | Using where |
+----+-------------+----------+------------+-------+-------------------+-------------------+---------+-------+------+----------+-------------+

key 列中显示 idx_dept_salary_date 表示查询使用了复合索引,优化了查询性能。

小结

复合索引是数据库优化中非常强大的工具,特别适用于多列查询和复杂查询模式。通过合理设计和使用复合索引,可以显著提高查询性能,减少I/O操作,提升数据库系统的整体效率。然而,复合索引的设计需要仔细考虑列的顺序和查询模式,以确保索引能够充分发挥作用。在实际应用中,通过定期监控和优化,可以最大化复合索引的优势,确保数据库的高效运行。

相关推荐
bjxiaxueliang37 分钟前
一文掌握SpringBoot:HTTP服务开发从入门到部署
spring boot·后端·http
野犬寒鸦13 小时前
从零起步学习并发编程 || 第一章:初步认识进程与线程
java·服务器·后端·学习
我爱娃哈哈13 小时前
SpringBoot + Flowable + 自定义节点:可视化工作流引擎,支持请假、报销、审批全场景
java·spring boot·后端
李梨同学丶15 小时前
0201好虫子周刊
后端
思想在飞肢体在追15 小时前
Springboot项目配置Nacos
java·spring boot·后端·nacos
Loo国昌18 小时前
【垂类模型数据工程】第四阶段:高性能 Embedding 实战:从双编码器架构到 InfoNCE 损失函数详解
人工智能·后端·深度学习·自然语言处理·架构·transformer·embedding
ONE_PUNCH_Ge19 小时前
Go 语言泛型
开发语言·后端·golang
良许Linux19 小时前
DSP的选型和应用
后端·stm32·单片机·程序员·嵌入式
不光头强19 小时前
spring boot项目欢迎页设置方式
java·spring boot·后端
怪兽毕设19 小时前
基于SpringBoot的选课调查系统
java·vue.js·spring boot·后端·node.js·选课调查系统