数据库MySQL学习——day13(索引与查询优化)
文章目录
- 1. 什么是索引?
- 1.1索引的作用:
- 1.2 索引的分类(常见类型)
- 2. 使用 EXPLAIN 分析查询计划
- 2.1 EXPLAIN 是什么?
- 2.2 type 类型优劣对比(性能排序):
- 3. 查询优化技巧
- 3.1 避免使用 SELECT *
- 3.2 使用 WHERE + 索引列进行筛选
- 3.3 建立合理的复合索引(左前缀原则)
- 3.4 避免在 WHERE 中对列做运算
- 3.5 LIMIT 分页时使用覆盖索引
- 4.实践任务演示
- 5. 总结
1. 什么是索引?
1.1索引的作用:
索引是数据库为了加快查找数据而设计的“查找目录”,本质上是用于快速定位数据的结构,类似于书籍的目录页。
没有索引时,MySQL 必须全表扫描,而有索引后可极大减少扫描行数。
1.2 索引的分类(常见类型)
类型 | 说明 |
---|---|
主键索引 | 自动为主键字段创建的索引,唯一且不允许为空 |
唯一索引 | 保证列值唯一,但允许空值 |
普通索引 | 一般创建在频繁查询的列上 |
复合索引 | 多列组合索引,加快多条件联合查询 |
全文索引 | 主要用于文本搜索(仅支持 MyISAM / InnoDB 的 FULLTEXT 索引) |
空间索引 | 用于地理信息系统(GIS)的特殊索引 |
- 示例:创建索引语法
- 创建普通索引:
CREATE INDEX idx_name ON users(name);
创建唯一索引:
CREATE UNIQUE INDEX idx_email ON users(email);
创建复合索引:
CREATE INDEX idx_name_age ON users(name, age);
删除索引:
DROP INDEX idx_name ON users;
2. 使用 EXPLAIN 分析查询计划
2.1 EXPLAIN 是什么?
EXPLAIN 可以告诉你一条 SQL 的执行方式(是否用了索引?用了哪种?是否全表扫描?)。
示例:
EXPLAIN SELECT * FROM users WHERE name = 'Tom';
EXPLAIN 关键字段解释:
字段名 | 含义 |
---|---|
id | 查询的执行顺序 ID(越大越先执行) |
select_type | 查询类型(SIMPLE/PRIMARY/SUBQUERY 等) |
table | 当前查询的表 |
type | 访问类型,性能越好越靠近 const |
possible_keys | 可以使用的索引 |
key | 实际使用的索引 |
rows | 扫描的行数,越少越快 |
Extra | 额外信息,如“Using where”、“Using index”、“Using temporary” 等 |
2.2 type 类型优劣对比(性能排序):
const > eq_ref > ref > range > index > ALL(全表扫描)
3. 查询优化技巧
3.1 避免使用 SELECT *
-- 差:读取所有字段
SELECT * FROM users;-- 优:只读取需要字段
SELECT name, email FROM users;
- 原因:
SELECT * 会读出所有字段,不利于索引覆盖
会增加网络传输、磁盘IO
3.2 使用 WHERE + 索引列进行筛选
-- 有 name 上索引
SELECT * FROM users WHERE name = 'Tom'; √-- 没用索引(函数包裹字段)
SELECT * FROM users WHERE UPPER(name) = 'TOM'; ×
- 原因:索引列上不能使用函数或表达式,否则失效。
3.3 建立合理的复合索引(左前缀原则)
CREATE INDEX idx_name_age ON users(name, age);-- 有效:用到索引的左边字段
SELECT * FROM users WHERE name = 'Tom'; √-- 有效:用到 name + age
SELECT * FROM users WHERE name = 'Tom' AND age = 20; √-- 无效:跳过 name,单用 age
SELECT * FROM users WHERE age = 20; ×
3.4 避免在 WHERE 中对列做运算
-- 索引失效
SELECT * FROM orders WHERE YEAR(order_date) = 2023;-- 推荐
SELECT * FROM orders WHERE order_date >= '2023-01-01' AND order_date < '2024-01-01';
3.5 LIMIT 分页时使用覆盖索引
-- 索引字段放前面,主键放后面,可减少回表
SELECT id FROM articles ORDER BY id LIMIT 10;
4.实践任务演示
任务 1:创建索引提升性能
-- 创建示例表
CREATE TABLE users (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50),email VARCHAR(100),age INT
);-- 插入大量测试数据(可用循环脚本)
-- 然后创建索引
CREATE INDEX idx_name ON users(name);
任务 2:使用 EXPLAIN 分析查询
EXPLAIN SELECT * FROM users WHERE name = 'Tom';
任务 3:对慢查询优化
SELECT * FROM users WHERE YEAR(created_at) = 2023;
优化后(快):
-- 前提:created_at 列有索引
SELECT * FROM users
WHERE created_at >= '2023-01-01' AND created_at < '2024-01-01';
5. 总结
- 索引类型对比:
类型 | 特点 |
---|---|
主键索引 | 自动创建,唯一 + 非空 |
唯一索引 | 唯一但可空 |
普通索引 | 无约束,用于加速查询 |
复合索引 | 多字段组合,加速多条件查询 |
- 查询优化建议:
优化点 | 说明 |
---|---|
避免 SELECT * | 减少读取列数,加快速度 |
WHERE 用索引列 | 建索引 + 合理查询 |
避免函数包裹列 | 否则索引失效 |
创建复合索引按使用频率 | 遵守“左前缀”原则 |
使用 EXPLAIN 分析语句 | 看是否使用索引,有无全表扫描 |