目录
- 一、索引
-
- 1、索引的作用
- [2、索引的原理(以 InnoDB 为例)](#2、索引的原理(以 InnoDB 为例))
- [3、索引命中(索引失效场景 & 优化)](#3、索引命中(索引失效场景 & 优化))
- 二、事务
- 三、基本的SQL优化
一、索引
1、索引的作用
加速查询效率,将原本的全表扫描(O (n))优化为索引查找(通常 O (log n)),大幅提升查询性能。
唯一索引:保证字段值的唯一性(如 UNIQUE INDEX);
排序优化:避免查询时额外的 ORDER BY 排序开销;
约束实现:主键、外键约束底层依赖索引实现。
代价:写操作(INSERT/UPDATE/DELETE)变慢:需要同步维护索引结构;
占用额外磁盘空间:索引数据需要持久化存储。
2、索引的原理(以 InnoDB 为例)
底层数据结构:B+ 树(MySQL InnoDB 引擎默认)
所有数据存储在叶子节点,非叶子节点仅存储索引键和指针,适合磁盘 I/O 操作;
叶子节点形成有序链表,支持范围查询和顺序遍历。
分类与原理:
1、聚簇索引(Clustered Index)
主键索引,数据行直接存储在索引树的叶子节点(索引即数据);
每张表只能有一个聚簇索引,查询效率最高。
2、二级索引(Secondary Index)
非主键索引,叶子节点存储主键值,查询时需先通过二级索引找到主键,再回表查询聚簇索引;
回表操作会带来额外开销,覆盖索引可避免回表。
核心思想:通过有序的树结构,将磁盘随机 I/O 转化为顺序 I/O,减少查询时的磁盘访问次数。
创建索引:

创建复合索引时,列与列之间用","隔开。
删除索引:
1、删除主键索引:
alter table 表名 drop primary key;
删除主键索引时不用指定索引名,因为表中只有一个主键
删除之前要把自增取消,如果存在自增列则报错
2、删除其他索引
alter table 表名 drop index 索引名;
3、索引命中(索引失效场景 & 优化)
1、索引命中的前提:查询条件符合索引的最左前缀原则,且未使用导致索引失效的操作。
2、常见索引失效场景(面试高频):
WHERE 子句中对索引列使用函数 / 运算(如 WHERE YEAR(create_time) = 2024);
使用 !=、NOT IN、IS NULL/IS NOT NULL 等否定条件;
模糊查询 LIKE '%xxx%'(以 % 开头);
违反最左前缀原则(如联合索引 (a,b,c),查询条件仅包含 b);
类型隐式转换(如字符串索引列传入数字参数)。
3、优化命中的方法:
遵循最左前缀原则设计联合索引;
避免在索引列上做运算 / 函数操作;
使用覆盖索引(查询字段均在索引中,避免回表);
合理控制索引数量,避免过多索引影响写性能。
什么是最左前缀原则:
最左前缀原则是联合索引的核心使用规则:创建联合索引 (a,b,c) 后,查询条件必须从最左侧的 a 开始连续匹配,才能命中对应部分的索引;跳过左侧字段直接用右侧字段,索引会失效。比如仅查 b=2 会全表扫描,而查 a=1 或 a=1 AND b=2 能命中索引。
二、事务
1、事务的作用
事务(Transaction)是数据库执行操作的最小逻辑单元,是一组要么全部成功、要么全部失败的 SQL 操作集合。
核心作用:保证数据的一致性与可靠性,避免部分操作成功、部分失败导致的数据混乱。
典型场景:转账操作(扣款 + 入账必须同时成功或同时失败)、订单创建(库存扣减 + 订单生成必须原子执行)。
2、事务的使用
sql
-- 1. 开启事务
START TRANSACTION; -- 或 BEGIN;
-- 2. 执行一组业务 SQL
UPDATE account SET balance = balance - 100 WHERE id = 1; -- 扣款
UPDATE account SET balance = balance + 100 WHERE id = 2; -- 入账
-- 3. 提交/回滚
COMMIT; -- 全部成功,提交事务,数据永久生效
ROLLBACK; -- 出现异常,回滚所有操作,数据恢复到执行前状态
自动提交:MySQL 默认开启 autocommit=1,每条 SQL 会自动作为独立事务提交;需手动开启事务才能实现多操作的原子性。
3、ACID特性(重点)
原子性(Atomicity):事务是最小执行单元,要么全部执行成功,要么全部失败回滚,不存在中间状态。
一致性(Consistency):事务执行前后,数据库的完整性约束(如余额不能为负)保持不变,数据从一个一致状态变为另一个一致状态。
隔离性(Isolation):事务执行前后,数据库的完整性约束(如余额不能为负)保持不变,数据从一个一致状态变为另一个一致状态。
持久性(Durability):事务一旦提交,对数据的修改就永久生效,即使数据库崩溃也不会丢失。
4、事物的隔离级别
并发事务会导致脏读、不可重复读、幻读问题,通过设置隔离级别来平衡性能与数据安全:
读未提交(Read Uncommitted):最低级别,事务能读到其他事务未提交的数据,问题最多。
读已提交(Read Committed):只能读到其他事务已提交的数据,解决脏读(Oracle 默认)。
可重复读(Repeatable Read):同一事务内多次读取同一数据结果一致,解决脏读 + 不可重复读(MySQL InnoDB 默认)。
串行化(Serializable):最高级别,事务串行执行,完全避免并发问题,但性能极低。
并发问题:
脏读:读到其他事务未提交的脏数据。
不可重复读:同一事务内,两次读取同一数据结果不同(其他事务修改并提交)。
幻读:同一事务内,两次查询的行数不同(其他事务插入 / 删除并提交)。
三、基本的SQL优化
核心分三类:
索引优化:给查询 / 关联字段建索引,遵循最左前缀原则,避免函数 / 运算导致索引失效;
语句优化:不用 SELECT *,用 JOIN 替代子查询,限制结果集行数,避免 ORDER BY RAND ();
结构优化:选择合适的数据类型,大数据量表分库分表,避免大事务。