1. 首页 > MySQL教程 > 正文

MySQL教程FG244-MySQL索引优化

Part01-基础概念与理论知识

1.1 MySQL索引概述

MySQL索引是数据库中用于提高查询效率的数据结构,通过创建索引,可以显著减少数据扫描的范围,提高查询速度。本教程将详细介绍MySQL索引的概念、类型和原理。风哥教程参考MySQL官方文档索引部分的相关内容。更多视频教程www.fgedu.net.cn

# MySQL索引概述
MySQL索引是数据库中用于提高查询效率的数据结构,通过创建索引,可以显著减少数据扫描的范围,提高查询速度。

# MySQL索引的重要性
1. 提高查询速度:通过索引,MySQL可以快速定位数据,减少数据扫描的范围
2. 加速排序和分组:索引可以加速ORDER BY和GROUP BY操作
3. 提高连接效率:索引可以加速表之间的连接操作
4. 确保数据唯一性:唯一索引可以确保数据的唯一性
5. 减少IO操作:索引可以减少磁盘IO操作,提高系统性能

# MySQL索引的工作原理
1. 索引是一种数据结构,通常是B树或B+树
2. 索引存储了表中列的值和对应的行指针
3. 查询时,MySQL通过索引快速定位到数据所在的位置
4. 索引可以大大减少数据扫描的范围,提高查询速度

# MySQL索引的优缺点
## 优点:
1. 提高查询速度
2. 加速排序和分组
3. 提高连接效率
4. 确保数据唯一性

## 缺点:
1. 占用存储空间
2. 增加写操作的开销(插入、更新、删除)
3. 维护索引需要额外的时间和资源
4. 过多的索引会影响性能

# MySQL索引的适用场景
1. 频繁用于查询条件的列
2. 频繁用于排序和分组的列
3. 频繁用于连接条件的列
4. 需要确保唯一性的列

1.2 MySQL索引类型

MySQL支持多种类型的索引,包括主键索引、唯一索引、普通索引、复合索引、全文索引等。学习交流加群风哥微信: itpux-com

MySQL索引类型:1. 主键索引:唯一标识表中的每一行,不能为NULL,一个表只能有一个主键索引;2. 唯一索引:确保列的值唯一,但允许NULL值;3. 普通索引:最基本的索引,没有唯一性限制;4. 复合索引:基于多个列创建的索引;5. 全文索引:用于全文搜索;6. 空间索引:用于地理空间数据。

1.3 MySQL索引原理

MySQL索引的原理是基于数据结构,如B树或B+树,通过这些数据结构,MySQL可以快速定位数据。学习交流加群风哥QQ113257174

# MySQL索引原理
1. B树索引:
– B树是一种平衡树,每个节点可以存储多个键值对
– B树的高度较低,查询效率高
– 适用于范围查询和精确查询

2. B+树索引:
– B+树是B树的变体,所有数据都存储在叶子节点
– 叶子节点之间有指针链接,便于范围查询
– MySQL的InnoDB引擎使用B+树作为索引结构

3. 哈希索引:
– 基于哈希表实现,查询速度快
– 适用于精确匹配,不支持范围查询
– MySQL的Memory引擎支持哈希索引

4. 全文索引:
– 基于倒排索引实现,用于全文搜索
– 支持复杂的文本搜索
– MySQL的MyISAM和InnoDB引擎支持全文索引

5. 空间索引:
– 用于地理空间数据
– 基于R树或GeoHash实现
– MySQL的MyISAM和InnoDB引擎支持空间索引

# 索引的存储结构
1. 聚簇索引:
– 数据和索引存储在一起
– InnoDB的主键索引是聚簇索引
– 查找速度快,但插入和更新可能较慢

2. 非聚簇索引:
– 数据和索引分开存储
– InnoDB的二级索引是非聚簇索引
– 查找需要回表,速度相对较慢

# 索引的工作流程
1. 查询时,MySQL首先检查是否有合适的索引
2. 如果有索引,MySQL使用索引定位数据
3. 如果没有索引,MySQL进行全表扫描
4. 索引可以大大减少数据扫描的范围,提高查询速度

Part02-生产环境规划与建议

2.1 索引设计策略

MySQL索引设计策略是确保索引有效性的重要措施,需要根据业务需求和数据特点制定合理的索引设计策略。风哥提示:生产环境中应制定完善的索引设计策略,确保索引的有效性。

索引设计策略:1. 选择合适的索引列:选择经常用于查询条件、排序和分组的列;2. 考虑索引选择性:选择选择性高的列作为索引;3. 合理使用复合索引:遵循最左前缀原则;4. 避免过度索引:每个表的索引数量不宜过多;5. 定期维护索引:定期重建索引,删除未使用的索引。

2.2 索引使用建议

MySQL索引使用建议是确保索引有效使用的重要措施,包括索引的创建、使用和维护等方面。更多学习教程公众号风哥教程itpux_com

# 索引使用建议
1. 选择合适的索引列:
– 经常用于WHERE条件的列
– 经常用于ORDER BY和GROUP BY的列
– 经常用于JOIN条件的列
– 选择性高的列(唯一值比例高的列)

2. 复合索引使用建议:
– 遵循最左前缀原则:复合索引的顺序应该与查询条件的顺序一致
– 将选择性高的列放在前面:提高索引的选择性
– 考虑查询覆盖:设计可以覆盖查询的复合索引,减少回表操作

3. 索引使用注意事项:
– 避免在索引列上使用函数:会使索引失效
– 避免使用LIKE ‘%…’:会导致全表扫描
– 避免使用OR:尽量使用IN代替OR
– 避免使用NULL:NULL会影响索引的使用
– 合理使用LIMIT:限制返回的数据量

4. 索引性能优化:
– 选择合适的索引类型:根据查询需求选择合适的索引类型
– 优化索引结构:合理设计索引结构,提高查询效率
– 监控索引使用情况:定期检查索引的使用情况
– 调整索引:根据查询需求调整索引结构

5. 索引维护建议:
– 定期重建索引:使用OPTIMIZE TABLE命令重建索引
– 删除未使用的索引:删除长期未使用的索引,减少维护开销
– 监控索引大小:监控索引的大小,及时调整
– 备份索引:定期备份索引,防止数据丢失

2.3 索引维护建议

MySQL索引维护是确保索引有效性的重要措施,包括索引的重建、优化和监控等方面。from MySQL:www.itpux.com

# 索引维护建议
1. 定期重建索引:
– 使用OPTIMIZE TABLE命令重建索引
– 重建索引可以消除碎片,提高索引效率
– 示例:OPTIMIZE TABLE users;

2. 删除未使用的索引:
– 使用pt-index-usage分析索引使用情况
– 删除长期未使用的索引,减少维护开销
– 示例:ALTER TABLE users DROP INDEX idx_unused;

3. 监控索引使用情况:
– 使用Performance Schema监控索引使用情况
– 查看sys.schema_index_statistics视图
– 示例:SELECT * FROM sys.schema_index_statistics WHERE table_schema = ‘test’;

4. 监控索引大小:
– 使用SHOW TABLE STATUS查看表的索引大小
– 示例:SHOW TABLE STATUS LIKE ‘users’;

5. 备份索引:
– 定期备份数据库,包括索引
– 使用mysqldump备份索引
– 示例:mysqldump -u root -p test > test_backup.sql

6. 索引优化:
– 根据查询需求调整索引结构
– 合并重复的索引
– 优化复合索引的顺序

7. 索引监控工具:
– pt-index-usage:分析索引使用情况
– MySQL Enterprise Monitor:监控索引性能
– Performance Schema:内置的性能监控工具

8. 索引维护计划:
– 制定定期索引维护计划
– 定期检查索引使用情况
– 及时调整索引结构

# 索引维护最佳实践
1. 定期重建索引:每季度或半年重建一次索引
2. 监控索引使用情况:每月检查一次索引使用情况
3. 删除未使用的索引:每季度清理一次未使用的索引
4. 备份索引:与数据库备份一起备份索引
5. 优化索引结构:根据查询需求及时调整索引结构

Part03-生产环境项目实施方案

3.1 索引设计

MySQL索引设计是确保索引有效性的基础,需要根据业务需求和数据特点设计合理的索引。

# 索引设计
# 步骤1:分析查询需求
# 收集常见的查询语句
SELECT * FROM users WHERE email = ‘user@example.com’;
SELECT * FROM users WHERE age > 18 ORDER BY created_at DESC;
SELECT u.name, o.amount FROM users u JOIN orders o ON u.id = o.user_id WHERE u.age > 18;

# 步骤2:分析数据特点
# 分析表结构
SHOW CREATE TABLE users;
SHOW CREATE TABLE orders;

# 分析数据分布
SELECT age, COUNT(*) FROM users GROUP BY age;
SELECT email, COUNT(*) FROM users GROUP BY email;

# 步骤3:设计索引
# 基于查询需求和数据特点设计索引
# 为users表设计索引
CREATE INDEX idx_email ON users(email);
CREATE INDEX idx_age_created_at ON users(age, created_at);

# 为orders表设计索引
CREATE INDEX idx_user_id ON orders(user_id);

# 步骤4:验证索引设计
# 分析查询执行计划
EXPLAIN SELECT * FROM users WHERE email = ‘user@example.com’;
EXPLAIN SELECT * FROM users WHERE age > 18 ORDER BY created_at DESC;
EXPLAIN SELECT u.name, o.amount FROM users u JOIN orders o ON u.id = o.user_id WHERE u.age > 18;

# 步骤5:调整索引设计
# 根据执行计划调整索引设计
# 例如,如果查询需要覆盖更多列,可以调整复合索引

# 索引设计最佳实践
1. 基于查询需求:根据常见的查询语句设计索引
2. 考虑数据分布:分析数据分布,选择选择性高的列作为索引
3. 合理使用复合索引:遵循最左前缀原则
4. 避免过度索引:每个表的索引数量不宜过多
5. 定期调整:根据查询需求的变化调整索引设计

3.2 索引创建

MySQL索引创建是实现索引设计的重要步骤,需要使用合适的SQL语句创建索引。

# 索引创建
# 步骤1:创建主键索引
# 创建表时指定主键
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(50),
email VARCHAR(100),
age INT,
created_at DATETIME
);

# 为现有表添加主键
ALTER TABLE users ADD PRIMARY KEY (id);

# 步骤2:创建唯一索引
# 创建唯一索引
CREATE UNIQUE INDEX idx_email ON users(email);

# 为现有表添加唯一索引
ALTER TABLE users ADD UNIQUE INDEX idx_email (email);

# 步骤3:创建普通索引
# 创建普通索引
CREATE INDEX idx_age ON users(age);

# 为现有表添加普通索引
ALTER TABLE users ADD INDEX idx_age (age);

# 步骤4:创建复合索引
# 创建复合索引
CREATE INDEX idx_age_created_at ON users(age, created_at);

# 为现有表添加复合索引
ALTER TABLE users ADD INDEX idx_age_created_at (age, created_at);

# 步骤5:创建全文索引
# 创建全文索引
CREATE FULLTEXT INDEX idx_name_fulltext ON users(name);

# 为现有表添加全文索引
ALTER TABLE users ADD FULLTEXT INDEX idx_name_fulltext (name);

# 步骤6:创建空间索引
# 创建空间索引
CREATE SPATIAL INDEX idx_location ON locations(point);

# 为现有表添加空间索引
ALTER TABLE locations ADD SPATIAL INDEX idx_location (point);

# 步骤7:验证索引创建
# 查看表的索引
SHOW INDEX FROM users;

# 查看索引大小
SHOW TABLE STATUS LIKE ‘users’;

# 索引创建最佳实践
1. 选择合适的索引类型:根据查询需求选择合适的索引类型
2. 命名规范:使用有意义的索引名称,便于管理
3. 避免过度索引:每个表的索引数量不宜过多
4. 考虑存储空间:索引会占用存储空间,需要合理规划
5. 测试验证:创建索引后测试查询性能,确保索引有效

3.3 索引优化

MySQL索引优化是确保索引有效性的重要措施,包括索引的调整、重建和删除等操作。

# 索引优化
# 步骤1:分析索引使用情况
# 使用pt-index-usage分析索引使用情况
pt-index-usage /var/log/mysql/slow.log

# 使用Performance Schema监控索引使用情况
SELECT * FROM performance_schema.table_io_waits_summary_by_index_usage WHERE object_schema = ‘test’ AND object_name = ‘users’;

# 步骤2:调整索引结构
# 合并重复的索引
ALTER TABLE users DROP INDEX idx_age, ADD INDEX idx_age_created_at (age, created_at);

# 调整复合索引的顺序
ALTER TABLE users DROP INDEX idx_age_created_at, ADD INDEX idx_created_at_age (created_at, age);

# 步骤3:重建索引
# 使用OPTIMIZE TABLE重建索引
OPTIMIZE TABLE users;

# 使用ALTER TABLE重建索引
ALTER TABLE users ENGINE=InnoDB;

# 步骤4:删除未使用的索引
# 删除未使用的索引
ALTER TABLE users DROP INDEX idx_unused;

# 步骤5:优化索引统计信息
# 更新索引统计信息
ANALYZE TABLE users;

# 步骤6:验证索引优化效果
# 分析查询执行计划
EXPLAIN SELECT * FROM users WHERE email = ‘user@example.com’;

# 测试查询响应时间
SELECT * FROM users WHERE email = ‘user@example.com’;

# 索引优化最佳实践
1. 定期分析索引使用情况:每季度分析一次索引使用情况
2. 及时调整索引结构:根据查询需求的变化调整索引结构
3. 重建索引:每半年重建一次索引,消除碎片
4. 删除未使用的索引:每季度清理一次未使用的索引
5. 优化索引统计信息:定期更新索引统计信息,确保查询优化器做出正确的决策

3.4 索引验证

MySQL索引验证是确保索引有效性的重要步骤,通过测试和监控,验证索引是否达到预期效果。

# 索引验证
# 步骤1:测试查询性能
# 测试索引查询性能
SELECT * FROM users WHERE email = ‘user@example.com’;
# 记录执行时间

# 测试无索引查询性能
# 临时禁用索引
SET SESSION optimizer_switch=’use_indexes=off’;
SELECT * FROM users WHERE email = ‘user@example.com’;
# 记录执行时间
SET SESSION optimizer_switch=’use_indexes=on’;

# 步骤2:分析执行计划
# 分析索引查询执行计划
EXPLAIN SELECT * FROM users WHERE email = ‘user@example.com’;

# 分析无索引查询执行计划
SET SESSION optimizer_switch=’use_indexes=off’;
EXPLAIN SELECT * FROM users WHERE email = ‘user@example.com’;
SET SESSION optimizer_switch=’use_indexes=on’;

# 步骤3:监控索引使用情况
# 使用Performance Schema监控索引使用情况
SELECT * FROM performance_schema.table_io_waits_summary_by_index_usage WHERE object_schema = ‘test’ AND object_name = ‘users’;

# 使用sys.schema_index_statistics监控索引使用情况
SELECT * FROM sys.schema_index_statistics WHERE table_schema = ‘test’ AND table_name = ‘users’;

# 步骤4:对比优化前后的性能
# 记录优化前的性能指标
# 记录优化后的性能指标
# 分析性能提升情况

# 步骤5:验证业务场景
# 在实际业务场景中验证索引性能
# 确保业务系统正常运行

# 步骤6:文档记录
# 记录索引验证结果
# 总结优化经验和教训

# 索引验证最佳实践
1. 测试多种场景:测试不同数据量、不同并发下的索引性能
2. 对比分析:对比优化前后的性能指标,评估优化效果
3. 实际验证:在实际业务场景中验证索引性能
4. 持续监控:持续监控索引使用情况,及时发现问题
5. 文档记录:记录索引验证过程和结果,便于后续参考

Part04-生产案例与实战讲解

4.1 单列索引优化案例

单列索引优化是MySQL索引优化的基础,以下是具体的单列索引优化案例。

# 单列索引优化案例
# 环境说明
# MySQL 8.0.29
# 数据库:test
# 表:users(100万行数据)
# 表结构:
# CREATE TABLE users (
# id INT PRIMARY KEY,
# name VARCHAR(50),
# email VARCHAR(100),
# age INT,
# created_at DATETIME
# );

# 问题描述
# 发现查询响应时间长,需要优化单列索引

# 解决方案
## 步骤1:分析查询需求
# 常见查询:
# 1. SELECT * FROM users WHERE email = ‘user@example.com’;
# 2. SELECT * FROM users WHERE age = 18;

## 步骤2:分析现有索引
# 查看现有索引
SHOW INDEX FROM users;

# 预期输出:
+——-+————+———-+————–+————-+———–+————-+———-+——–+——+————+———+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+——-+————+———-+————–+————-+———–+————-+———-+——–+——+————+———+
| users | 0 | PRIMARY | 1 | id | A | 1000000 | NULL | NULL | | BTREE | |
+——-+————+———-+————–+————-+———–+————-+———-+——–+——+————+———+

## 步骤3:添加缺失的索引
# 添加email列索引
ALTER TABLE users ADD INDEX idx_email (email);

# 添加age列索引
ALTER TABLE users ADD INDEX idx_age (age);

## 步骤4:验证索引优化效果
# 分析查询1的执行计划
EXPLAIN SELECT * FROM users WHERE email = ‘user@example.com’;

# 预期输出:
+—-+————-+——-+————+——+—————+———+———+——-+——+———-+——-+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+——-+————+——+—————+———+———+——-+——+———-+——-+
| 1 | SIMPLE | users | NULL | ref | idx_email | idx_email | 102 | const | 1 | 100.00 | NULL |
+—-+————-+——-+————+——+—————+———+———+——-+——+———-+——-+

# 分析查询2的执行计划
EXPLAIN SELECT * FROM users WHERE age = 18;

# 预期输出:
+—-+————-+——-+————+——+—————+———+———+——-+——-+———-+——-+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+——-+————+——+—————+———+———+——-+——-+———-+——-+
| 1 | SIMPLE | users | NULL | ref | idx_age | idx_age | 5 | const | 100000 | 100.00 | NULL |
+—-+————-+——-+————+——+—————+———+———+——-+——-+———-+——-+

## 步骤5:测试查询响应时间
# 测试查询1
SELECT * FROM users WHERE email = ‘user@example.com’;
# 优化前:0.5秒
# 优化后:0.01秒

# 测试查询2
SELECT * FROM users WHERE age = 18;
# 优化前:1.0秒
# 优化后:0.05秒

# 处理效果
# 成功优化了单列索引
# 添加了email列和age列的索引
# 查询响应时间显著减少
# 提高了系统性能

4.2 复合索引优化案例

复合索引优化是MySQL索引优化的重要组成部分,以下是具体的复合索引优化案例。

# 复合索引优化案例
# 环境说明
# MySQL 8.0.29
# 数据库:test
# 表:users(100万行数据)
# 表结构:
# CREATE TABLE users (
# id INT PRIMARY KEY,
# name VARCHAR(50),
# email VARCHAR(100),
# age INT,
# created_at DATETIME
# );

# 问题描述
# 发现排序查询响应时间长,需要优化复合索引

# 解决方案
## 步骤1:分析查询需求
# 常见查询:
# SELECT * FROM users WHERE age > 18 ORDER BY created_at DESC;

## 步骤2:分析现有索引
# 查看现有索引
SHOW INDEX FROM users;

# 预期输出:
+——-+————+———-+————–+————-+———–+————-+———-+——–+——+————+———+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+——-+————+———-+————–+————-+———–+————-+———-+——–+——+————+———+
| users | 0 | PRIMARY | 1 | id | A | 1000000 | NULL | NULL | | BTREE | |
| users | 1 | idx_age | 1 | age | A | 1000 | NULL | NULL | YES | BTREE | |
+——-+————+———-+————–+————-+———–+————-+———-+——–+——+————+———+

## 步骤3:分析执行计划
# 分析查询执行计划
EXPLAIN SELECT * FROM users WHERE age > 18 ORDER BY created_at DESC;

# 预期输出:
+—-+————-+——-+————+——+—————+———+———+——+———+———-+—————-+-
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+——-+————+——+—————+———+———+——+———+———-+—————-+-
| 1 | SIMPLE | users | NULL | range | idx_age | idx_age | 5 | NULL | 900000 | 100.00 | Using index condition; Using filesort |
+—-+————-+——-+————+——+—————+———+———+——+———+———-+—————-+-

## 步骤4:添加复合索引
# 添加age和created_at的复合索引
ALTER TABLE users ADD INDEX idx_age_created_at (age, created_at);

## 步骤5:验证复合索引优化效果
# 分析查询执行计划
EXPLAIN SELECT * FROM users WHERE age > 18 ORDER BY created_at DESC;

# 预期输出:
+—-+————-+——-+————+——+—————+——————+———+——+———+———-+—————-+-
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+——-+————+——+—————+——————+———+——+———+———-+—————-+-
| 1 | SIMPLE | users | NULL | range | idx_age,idx_age_created_at | idx_age_created_at | 5 | NULL | 900000 | 100.00 | Using index condition |
+—-+————-+——-+————+——+—————+——————+———+——+———+———-+—————-+-

## 步骤6:测试查询响应时间
# 测试查询
SELECT * FROM users WHERE age > 18 ORDER BY created_at DESC LIMIT 10;
# 优化前:2.0秒
# 优化后:0.05秒

# 处理效果
# 成功优化了复合索引
# 添加了age和created_at的复合索引
# 避免了文件排序,提高了查询性能
# 查询响应时间显著减少

4.3 索引维护案例

索引维护是MySQL索引优化的重要组成部分,以下是具体的索引维护案例。

# 索引维护案例
# 环境说明
# MySQL 8.0.29
# 数据库:test
# 表:users(100万行数据)

# 问题描述
# 发现索引性能下降,需要维护索引

# 解决方案
## 步骤1:分析索引使用情况
# 使用pt-index-usage分析索引使用情况
pt-index-usage /var/log/mysql/slow.log

# 使用Performance Schema监控索引使用情况
SELECT * FROM performance_schema.table_io_waits_summary_by_index_usage WHERE object_schema = ‘test’ AND object_name = ‘users’;

## 步骤2:识别未使用的索引
# 查看未使用的索引
SELECT * FROM sys.schema_unused_indexes WHERE table_schema = ‘test’;

## 步骤3:删除未使用的索引
# 删除未使用的索引
ALTER TABLE users DROP INDEX idx_unused;

## 步骤4:重建索引
# 使用OPTIMIZE TABLE重建索引
OPTIMIZE TABLE users;

# 或者使用ALTER TABLE重建索引
ALTER TABLE users ENGINE=InnoDB;

## 步骤5:更新索引统计信息
# 更新索引统计信息
ANALYZE TABLE users;

## 步骤6:验证索引维护效果
# 分析查询执行计划
EXPLAIN SELECT * FROM users WHERE email = ‘user@example.com’;

# 测试查询响应时间
SELECT * FROM users WHERE email = ‘user@example.com’;

## 步骤7:监控索引性能
# 持续监控索引使用情况
SELECT * FROM performance_schema.table_io_waits_summary_by_index_usage WHERE object_schema = ‘test’ AND object_name = ‘users’;

# 处理效果
# 成功维护了索引
# 删除了未使用的索引,重建了索引,更新了索引统计信息
# 索引性能得到提升
# 查询响应时间减少

4.4 索引性能调优案例

索引性能调优是MySQL索引优化的高级阶段,以下是具体的索引性能调优案例。

# 索引性能调优案例
# 环境说明
# MySQL 8.0.29
# 数据库:test
# 表:users(100万行数据)
# 表:orders(500万行数据)

# 问题描述
# 发现多表连接查询响应时间长,需要优化索引性能

# 原始查询
SELECT
u.name,
o.order_id,
o.amount
FROM
users u
JOIN
orders o ON u.id = o.user_id
WHERE
u.age > 18
AND o.created_at BETWEEN ‘2024-01-01’ AND ‘2024-12-31’
ORDER BY
o.amount DESC
LIMIT 10;

# 解决方案
## 步骤1:分析执行计划
EXPLAIN SELECT
u.name,
o.order_id,
o.amount
FROM
users u
JOIN
orders o ON u.id = o.user_id
WHERE
u.age > 18
AND o.created_at BETWEEN ‘2024-01-01’ AND ‘2024-12-31’
ORDER BY
o.amount DESC
LIMIT 10;

# 预期输出:
+—-+————-+——-+————+——+—————+———+———+——————+———+———-+———————————+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+——-+————+——+—————+———+———+——————+———+———-+———————————+
| 1 | SIMPLE | u | NULL | ALL | PRIMARY | NULL | NULL | NULL | 1000000 | 90.00 | Using where |
| 1 | SIMPLE | o | NULL | ref | idx_user_id | idx_user_id | 4 | test.u.id | 5 | 30.00 | Using where; Using temporary; Using filesort |
+—-+————-+——-+————+——+—————+———+———+——————+———+———-+———————————+

## 步骤2:优化索引
# 添加users表的age索引
ALTER TABLE users ADD INDEX idx_age (age);

# 添加orders表的复合索引
ALTER TABLE orders ADD INDEX idx_user_id_created_at_amount (user_id, created_at, amount);

## 步骤3:优化SQL语句
# 调整JOIN顺序,使用小表驱动大表
SELECT
u.name,
o.order_id,
o.amount
FROM
users u
JOIN
orders o ON u.id = o.user_id
WHERE
u.age > 18
AND o.created_at BETWEEN ‘2024-01-01’ AND ‘2024-12-31’
ORDER BY
o.amount DESC
LIMIT 10;

## 步骤4:验证索引性能调优效果
# 分析优化后的执行计划
EXPLAIN SELECT
u.name,
o.order_id,
o.amount
FROM
users u
JOIN
orders o ON u.id = o.user_id
WHERE
u.age > 18
AND o.created_at BETWEEN ‘2024-01-01’ AND ‘2024-12-31’
ORDER BY
o.amount DESC
LIMIT 10;

# 预期输出:
+—-+————-+——-+————+——+———————————-+———————————-+———+——————+———+———-+—————-+-
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+——-+————+——+———————————-+———————————-+———+——————+———+———-+—————-+-
| 1 | SIMPLE | u | NULL | range | PRIMARY,idx_age | idx_age | 5 | NULL | 900000 | 100.00 | Using index condition |
| 1 | SIMPLE | o | NULL | ref | idx_user_id,idx_user_id_created_at_amount | idx_user_id_created_at_amount | 4 | test.u.id | 5 | 30.00 | Using index condition |
+—-+————-+——-+————+——+———————————-+———————————-+———+——————+———+———-+—————-+-

## 步骤5:测试查询响应时间
# 优化前:5.0秒
# 优化后:0.1秒

# 处理效果
# 成功优化了索引性能
# 添加了必要的索引,调整了SQL语句
# 查询响应时间从5.0秒减少到0.1秒
# 提高了系统性能

Part05-风哥经验总结与分享

通过多年的MySQL数据库管理经验,我总结了以下关于MySQL索引优化的关键点:

风哥提示:MySQL索引优化是一个持续的过程,需要根据业务需求和数据特点不断调整和优化。

1. 索引设计:根据查询需求和数据特点设计合理的索引,选择选择性高的列作为索引。

2. 复合索引:合理使用复合索引,遵循最左前缀原则,将选择性高的列放在前面。

3. 索引维护:定期重建索引,删除未使用的索引,更新索引统计信息。

4. 索引使用:避免在索引列上使用函数,避免使用LIKE ‘%…’,避免使用OR。

5. 性能验证:定期测试查询性能,对比优化前后的效果,确保索引有效。

6. 持续监控:持续监控索引使用情况,及时发现和解决索引问题。

7. 平衡考虑:在索引的数量和性能之间取得平衡,避免过度索引。

生产环境最佳实践:1. 建立完善的索引体系:根据查询需求设计合理的索引;2. 定期维护索引:每季度或半年重建一次索引,删除未使用的索引;3. 监控索引使用情况:每月检查一次索引使用情况,及时调整索引;4. 优化复合索引:遵循最左前缀原则,将选择性高的列放在前面;5. 避免过度索引:每个表的索引数量不宜过多,一般不超过5个;6. 测试验证:创建索引后测试查询性能,确保索引有效;7. 培训开发人员:培训开发人员索引优化技能,提高代码质量;8. 使用工具:使用专业的索引优化工具,如pt-index-usage、MySQL Enterprise Monitor等;9. 文档化:记录索引设计和维护过程,便于后续参考;10. 持续学习:关注MySQL新版本的索引特性,及时应用新特性。

GF-MySQL数据库培训文档系列

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息