一、索引为什么会失效(前置知识)
MySQL 索引本质是基于 B+ 树的有序结构进行查找。当查询条件无法命中索引树的查找路径时,就只能扫描更多的数据页甚至全表扫描,导致索引失效。
更通俗的说:
索引能否使用,取决于查询条件能否映射到已经建立好的索引结构上,若否则只能全表扫描。
一旦破坏原有有序性、跳过索引前缀或让字段被处理,就无法精准定位数据,自然索引就会失效
二、常见索引失效情况
-
对索引字段使用函数
示例:
sqlselect * from t_user where upper(name) = 'TOM';因为函数改变了索引值,索引树无法直接对比
MySQL 会转成:
遍历 → 对每行执行函数 → 比较
➡ 不能走索引,退化为全表扫描
-
对索引字段做表达式计算
sqlselect * from t_user where age + 1 = 20; 因为函数改变了索引值,索引树无法直接对比➡ 不能走索引,退化为全表扫描 -
存在隐式类型转换
常见于 varchar 与 int 比较
sqlselect * from t_user where phone = 1300000001;phone 为 varchar,比较时会转换成 int,相当于:
sqlselect * from t_user where cast(phone as signed int) = 1300000001; MySQL 自动转换:CAST(phone AS signed) → 新值不在索引树里➡ 索引失效 -
like 以通配符开头
sqlselect * from t_user where name like '%abc'; MySQL 自动转换:CAST(phone AS signed) → 新值不在索引树里➡ 索引失效 -
联合索引不满足最左前缀原则
联合索引 (a, b, c),可匹配:
sqlwhere a = 1 where a = 1 and b = 2 where a = 1 and c = 3 where b = 2 and a = 1无法匹配:
sqlwhere b = 2 where c = 3 where b = 2 and c = 3所谓最左前缀法则,简单来说就是违背了b+树底层的有序性,必须从最左边开始,⽽⽆ 中断跳跃
-
OR 条件中一侧无索引
sqlselect * from t_user where id = 1 or age = 18;如果 age 无索引
MySQL 无法同时走索引 → 回退全表扫描(其实最本质的原因是它是或而不是短路或)
解决:给 age 加索引 或拆查询
三、MySQL 日志机制
MySQL 使用多种日志来保证数据安全性、可恢复性与一致性,主要包含 Redo Log、Undo Log 和 BinLog。
1. Redo Log(重做日志)
简单来说:数据库崩溃,我可以快速恢复
作用:数据库崩溃后恢复已提交数据,保证持久性(事务中的 D)
记录内容:对数据页的物理修改
写入时机:事务提交时写入磁盘
示例理解:
管理员修改档案书 5 上的余额
Redo Log 记录:书 5 某位置数值修改(500 → 400)
若数据库崩溃
重启后根据 Redo Log 恢复为 400
数据即使未落盘,也能在数据库恢复后重建修改结果
2. Undo Log(回滚日志)
简单来说:写错了我可以撤销
作用:
-
支持事务回滚,保证原子性(事务中的 A)
-
支持 MVCC,多版本并发控制
记录内容:数据变更的反向操作
示例理解:
原 balance = 100,被改成 200
Undo Log 记录:撤销为 100
回滚时按记录恢复
其他事务若不可见该修改,通过版本链读 Undo Log 中的旧版本(MVCC)
3. BinLog(二进制日志)
简单来说:记录所有对数据库产生改动的操作,用于数据备份、主从同步和崩溃后的恢复。
属于 Server 层日志,用于备份与主从同步
记录内容:所有表结构变更与表数据修改(DML、DDL)
不记录:select、show 等查询语句
BinLog 日志格式
| 格式 | 记录内容 | 优点 | 缺点 |
|---|---|---|---|
| Statement | 原 SQL 语句 | 空间小 | 存在同步一致性风险 |
| Row | 每行记录改变前后值 | 最一致 | 文件大 |
| Mixed | MySQL 自适应选择 | 兼顾性能与一致性 |
示例说明:以图书馆为例
总馆记录:谁修改了哪本书
分馆根据记录同步
Row 模式中会记录 balance 500 → 400 的细节变化
四、总结
| 内容 | 主要作用 |
|---|---|
| 索引使用失败 | 查询无法在索引树上精准定位 |
| Redo Log | 崩溃恢复,保证已提交不丢失 |
| Undo Log | 回滚和 MVCC,保证未提交不生效 |
| BinLog | 数据备份与主从同步 |