当前位置: 首页 > news >正文

MySQL 索引与事务详解

MySQL 索引与事务详解

一、索引(Index)

1. 索引的作用与原理

索引是数据库的"目录",能够大幅提高查询速度,但会增加写入开销。MySQL 使用 B+Tree 作为主要索引结构。

2. 索引类型

(1) 普通索引
CREATE INDEX idx_name ON users(name);  -- 创建
DROP INDEX idx_name ON users;         -- 删除
(2) 唯一索引
CREATE UNIQUE INDEX idx_email ON users(email);
(3) 主键索引(自动创建)
ALTER TABLE users ADD PRIMARY KEY(id);
(4) 复合索引(最左前缀原则)
CREATE INDEX idx_name_age ON users(name, age);
-- 能使用索引的情况:
-- WHERE name = '张三'
-- WHERE name = '张三' AND age = 25
-- WHERE name LIKE '张%'
-- 不能使用索引的情况:
-- WHERE age = 25
-- WHERE age = 25 AND name = '张三'

3. 索引优化技巧

  • 为 WHERE、JOIN、ORDER BY 涉及的列创建索引
  • 避免过度索引(每个索引占用存储空间并影响写入性能)
  • 使用 EXPLAIN 分析查询:
EXPLAIN SELECT * FROM users WHERE name = '张三';

4. 索引失效的常见情况

  • 使用 !=NOT INIS NULLIS NOT NULL
  • 对索引列使用函数:WHERE YEAR(create_time) = 2023
  • 类型转换:WHERE name = 123(name 是字符串类型)
  • 模糊查询以通配符开头:WHERE name LIKE '%三'

二、事务(Transaction)

1. 事务的特性(ACID)

  • 原子性(Atomicity):事务是不可分割的工作单位
  • 一致性(Consistency):事务执行前后数据库保持一致状态
  • 隔离性(Isolation):事务之间互不干扰
  • 持久性(Durability):事务提交后永久生效

2. 事务基本操作

START TRANSACTION;  -- 或 BEGIN
-- 执行SQL语句
INSERT INTO orders(user_id, amount) VALUES(1, 100);
UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;
COMMIT;  -- 提交
-- 或 ROLLBACK;  -- 回滚

3. 事务隔离级别

隔离级别脏读不可重复读幻读说明
READ UNCOMMITTED性能最高,安全性最低
READ COMMITTED×Oracle默认级别
REPEATABLE READ××MySQL默认级别
SERIALIZABLE×××安全性最高,性能最低

查看和设置隔离级别:

SELECT @@transaction_isolation;  -- 查看当前隔离级别
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;  -- 设置隔离级别

4. 事务中的常见问题

(1) 脏读(Dirty Read)

事务A读取了事务B未提交的数据

(2) 不可重复读(Non-repeatable Read)

事务A多次读取同一数据,期间事务B修改了该数据,导致事务A读取结果不一致

(3) 幻读(Phantom Read)

事务A读取某个范围的数据,期间事务B插入了新数据,事务A再次读取时出现"幻行"

5. 事务最佳实践

  • 尽量缩短事务执行时间
  • 避免在事务中进行远程调用或耗时操作
  • 合理设置隔离级别(通常使用默认的 REPEATABLE READ)
  • 处理死锁:
-- 查看最近死锁信息
SHOW ENGINE INNODB STATUS;

三、索引与事务的实际应用示例

-- 创建带索引的表
CREATE TABLE orders (id INT AUTO_INCREMENT PRIMARY KEY,user_id INT NOT NULL,amount DECIMAL(10,2) NOT NULL,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,INDEX idx_user_id (user_id),INDEX idx_created_at (created_at)
);-- 事务操作:下单并扣款
START TRANSACTION;INSERT INTO orders (user_id, amount) VALUES (1, 99.99);
UPDATE accounts SET balance = balance - 99.99 WHERE user_id = 1;-- 检查余额是否足够
SELECT balance FROM accounts WHERE user_id = 1 FOR UPDATE;-- 如果余额足够则提交,否则回滚
COMMIT;
-- 或 ROLLBACK;

四、高级话题

1. 覆盖索引

查询的列都包含在索引中,无需回表查询

CREATE INDEX idx_covering ON users(name, age);
SELECT name, age FROM users WHERE name = '张三';  -- 使用覆盖索引

2. 行锁、表锁与间隙锁

  • InnoDB 默认使用行锁
  • 某些情况会升级为表锁(如无索引更新)
  • 间隙锁防止幻读(在 REPEATABLE READ 级别下)

3. 保存点(Savepoint)

START TRANSACTION;
-- 操作1
SAVEPOINT sp1;
-- 操作2
ROLLBACK TO sp1;  -- 回滚到保存点
COMMIT;

掌握索引和事务是 MySQL 高效使用的关键,合理运用可以大幅提升应用性能和可靠性。

相关文章:

  • 在线文章系统自动化测试报告
  • 工业声纹采集设备的市场需求趋势简析
  • Qwen3 开源!深度对比 DeepSeek,一文选对模型
  • 巧记英语四级单词 Unit6-下【晓艳老师版】
  • 首发记忆行车方案与座舱智能管家,佑驾创新“抢跑”驾舱融合市场
  • GTC Taipei 2025 医疗域前瞻:从AI代理到医疗生态,解码医疗健康与生命科学的未来图景
  • CKA和CKS认证的介绍、学习、备考指南
  • 制作一款打飞机游戏30:动画系统
  • 业务层在事务中高频创建动态表然后删除或者回滚导致 pg_dump 概率出现备份失败问题分析
  • Python入门:流程控制练习
  • mmap核心原理和用途及其与内存映射段的关系
  • C++类与对象基础
  • FPGA 38 ,FPGA 网络通信协议栈基础,ARP 协议深度解析与模块划分( ARP与以太网帧,以及ARP模块常用文件 )
  • 【Stable Diffusion】文生图进阶指南:采样器、噪声调度与迭代步数的解析
  • 实习技能记录【5】-----项目中消息传递到ui层的方法
  • Knife4j 接口文档添加登录验证流程分析
  • 如何防止 ES 被 Linux OOM Killer 杀掉
  • C++日更八股--first
  • 狼人杀中的智能策略:解析AI如何理解复杂社交游戏
  • 代码随想录算法训练营 Day35 动态规划Ⅲ 0-1背包问题
  • 非法收受财物逾1648万,湖南原副厅级干部康月林一审被判十年半
  • 人民日报:应对外贸行业风险挑战,稳企业就是稳就业
  • 清华姚班,正走出一支军团
  • 国家统计局:一季度规模以上工业企业利润延续持续恢复态势
  • 持续更新丨伊朗内政部长:港口爆炸已致14人死亡
  • 我驻阿巴斯总领馆:将持续跟踪港口爆炸事件进展,全力确保中方人员安全