MySQL重点梳理

目录

[Day 1:SQL基础](#Day 1:SQL基础)

[1. 什么是SQL?(Structured Query Language)](#1. 什么是SQL?(Structured Query Language))

[2. SQL语句有哪些分类?](#2. SQL语句有哪些分类?)

🍉区分:

🍉为什么update/delete一定要加where?

[3. 增删改查(CRUD)](#3. 增删改查(CRUD))

🍉什么是CRUD?

[4. SELECT查询执行顺序(重点)](#4. SELECT查询执行顺序(重点))

[5. Where和Having区别(面试常问)](#5. Where和Having区别(面试常问))

[6. GROUP BY是什么?⭐⭐⭐](#6. GROUP BY是什么?⭐⭐⭐)

[7. JOIN是什么?⭐⭐⭐⭐](#7. JOIN是什么?⭐⭐⭐⭐)

[Day 2:MySQL索引 ⭐](#Day 2:MySQL索引 ⭐)

[1. 什么是索引?(必背)](#1. 什么是索引?(必背))

[2. 为什么需要索引?](#2. 为什么需要索引?)

[3. 索引的底层结构是什么?⭐⭐⭐⭐](#3. 索引的底层结构是什么?⭐⭐⭐⭐)

🍉为什么使用B+Tree?

[4. 为什么不用二叉树?为什么不用Hash索引?⭐⭐⭐⭐](#4. 为什么不用二叉树?为什么不用Hash索引?⭐⭐⭐⭐)

[5. B+Tree是什么?⭐⭐⭐⭐⭐](#5. B+Tree是什么?⭐⭐⭐⭐⭐)

[6. 索引的优缺点 ⭐⭐⭐⭐](#6. 索引的优缺点 ⭐⭐⭐⭐)

[7. 什么字段适合建立索引?⭐⭐⭐⭐](#7. 什么字段适合建立索引?⭐⭐⭐⭐)

🍉什么字段不适合?

8、为什么B+Tree特别适合范围查询?

9、那B+Tree和B树相比,有什么区别?为什么数据库更喜欢B+Tree?

[Day 3:MySQL 索引进阶 🔥](#Day 3:MySQL 索引进阶 🔥)

[1. 什么是聚簇索引?🔥🔥🔥](#1. 什么是聚簇索引?🔥🔥🔥)

[2. 什么是二级索引?🔥🔥🔥](#2. 什么是二级索引?🔥🔥🔥)

[3. 什么是回表?什么是覆盖索引?🔥🔥🔥(高频)](#3. 什么是回表?什么是覆盖索引?🔥🔥🔥(高频))

[4. 什么是联合索引?什么是最左匹配原则?🔥🔥🔥🔥](#4. 什么是联合索引?什么是最左匹配原则?🔥🔥🔥🔥)

[5. 哪些情况可能导致索引失效?🔥🔥🔥🔥(高频)](#5. 哪些情况可能导致索引失效?🔥🔥🔥🔥(高频))

[6. 为什么不建议 select * ?🔥🔥](#6. 为什么不建议 select * ?🔥🔥)

7、为什么①通常可以正常利用索引,而②对索引列使用函数后可能无法正常利用这个索引?

[Day 4:MySQL 事务篇 🧩](#Day 4:MySQL 事务篇 🧩)

[1. 什么是事务?💎为什么需要事务?🔷](#1. 什么是事务?💎为什么需要事务?🔷)

[3. 事务MySQL中怎么使用?🔷](#3. 事务MySQL中怎么使用?🔷)

[4. 什么是 ACID?💎💎](#4. 什么是 ACID?💎💎)

[5. 并发事务会出现什么问题?💎💎](#5. 并发事务会出现什么问题?💎💎)

[① 脏读 💎](#① 脏读 💎)

[②不可重复读 💎](#②不可重复读 💎)

[③幻读 💎](#③幻读 💎)

[6. MySQL事务隔离级别 💎💎](#6. MySQL事务隔离级别 💎💎)

[7. MySQL InnoDB 默认隔离级别 💎💎](#7. MySQL InnoDB 默认隔离级别 💎💎)

[8. 四种隔离级别解决什么问题?💎](#8. 四种隔离级别解决什么问题?💎)

[Day 5:MVCC + MySQL 锁 🛡️](#Day 5:MVCC + MySQL 锁 🛡️)

[1、什么是 MVCC?🔥🔥🔥](#1、什么是 MVCC?🔥🔥🔥)

[2 、为什么需要 MVCC?🔥🔥🔥](#2 、为什么需要 MVCC?🔥🔥🔥)

[3、undo log的两大作用:](#3、undo log的两大作用:)

[4、Read View](#4、Read View)

[🍉为什么 InnoDB 的 Repeatable Read(可重复读)能够解决不可重复读问题?请从undo log、MVCC、版本链和 Read View 的角度解释。](#🍉为什么 InnoDB 的 Repeatable Read(可重复读)能够解决不可重复读问题?请从undo log、MVCC、版本链和 Read View 的角度解释。)

5、什么是快照读和当前读?🔥🔥🔥

6、什么是共享锁和排他锁?

[表锁 vs 行锁](#表锁 vs 行锁)

[记录锁(Record Lock)vs 间隙锁(Gap Lock)](#记录锁(Record Lock)vs 间隙锁(Gap Lock))

[为啥(临键锁) Next-Key Lock 能帮助防止幻读?🔥🔥🔥🔥](#为啥(临键锁) Next-Key Lock 能帮助防止幻读?🔥🔥🔥🔥)

[7、InnoDB 在 RR 隔离级别下,是怎么处理幻读问题的?](#7、InnoDB 在 RR 隔离级别下,是怎么处理幻读问题的?)

[8、为什么说 InnoDB 的查询条件如果没有合适的索引,可能导致"锁范围扩大",甚至表现得像锁表?](#8、为什么说 InnoDB 的查询条件如果没有合适的索引,可能导致“锁范围扩大”,甚至表现得像锁表?)

🍉什么情况下行锁可能退化成类似"锁表"的效果?

[🍉快照读 && 当前读](#🍉快照读 && 当前读)

[9、为什么 SELECT ... FOR UPDATE 不能像普通 SELECT 一样只读取历史快照,而要读取当前最新的数据并加锁?](#9、为什么 SELECT ... FOR UPDATE 不能像普通 SELECT 一样只读取历史快照,而要读取当前最新的数据并加锁?)

[🍉事务 A COMMIT 之后,事务 B 会发生什么?](#🍉事务 A COMMIT 之后,事务 B 会发生什么?)

[🍉如果事务 A 还是持有 X Lock,但事务 B 执行select](#🍉如果事务 A 还是持有 X Lock,但事务 B 执行select)

[事务 B 会不会被阻塞?为什么?](#事务 B 会不会被阻塞?为什么?)

[Day6:SQL 优化与 EXPLAIN 🔥🔥🔥🔥](#Day6:SQL 优化与 EXPLAIN 🔥🔥🔥🔥)

[第一题 🔥🔥🔥:什么是慢 SQL?](#第一题 🔥🔥🔥:什么是慢 SQL?)

[第二题 🔥🔥🔥🔥:EXPLAIN 是干什么的?](#第二题 🔥🔥🔥🔥:EXPLAIN 是干什么的?)

[第三题 🔥🔥🔥🔥:](#第三题 🔥🔥🔥🔥:)

[为什么不能看到 key != NULL、SQL 使用了索引,就直接判断"这条 SQL 性能很好"?](#为什么不能看到 key != NULL、SQL 使用了索引,就直接判断“这条 SQL 性能很好”?)

[为什么 Extra = Using index 通常是一个比较好的信号?](#为什么 Extra = Using index 通常是一个比较好的信号?)

第四题:SQL优化---深分页

[Day7:InnoDB 底层 + MySQL 日志体系](#Day7:InnoDB 底层 + MySQL 日志体系)

[1、什么是 Buffer Pool?InnoDB 为什么需要 Buffer Pool?](#1、什么是 Buffer Pool?InnoDB 为什么需要 Buffer Pool?)

[2、是不是每执行一次 UPDATE,MySQL 都要立刻把修改后的数据写回磁盘?](#2、是不是每执行一次 UPDATE,MySQL 都要立刻把修改后的数据写回磁盘?)

[3、既然有了 redo log,为什么还需要 binlog?redo log 和 binlog 有什么区别?](#3、既然有了 redo log,为什么还需要 binlog?redo log 和 binlog 有什么区别?)

[4、为什么 MySQL 需要两阶段提交?](#4、为什么 MySQL 需要两阶段提交?)

[5、redo log 为什么叫"循环写"? binlog叫"追加写"?](#5、redo log 为什么叫“循环写”? binlog叫“追加写”?)

6、一个update的背后流程图


Day 1:SQL基础

1. 什么是SQL?(Structured Query Language)

回答:

是一种用于 操作关系型数据库的语言。

主要用于对数据库中的数据进行:

定义、操作、查询、控制。

比如:

MySQL、Oracle(/ˈɔːrəkəl/)、PostgreSQL(波斯格瑞) 等关系型数据库都支持SQL


2. SQL语句有哪些分类?

MySQL中常见分为:

① DDL(Data Definition Language)

是 数据定义语言,主要用来 定义数据库对象结构

比如数据库、表、字段等

常见操作包括 create、alter、drop、truncate。

create用于创建数据库对象,比如创建表

alter用于修改数据库对象结构,如增加字段、修改字段类型、删除字段等。

🍉区分:

drop:删除整个表对象,表结构和数据都会被删除。

truncate:清空表中的所有数据,但是保留表的结构和字段,之后仍然可以继续使用这个表。


② DML(Data Manipulation Language)

是 数据操作语言,主要用于操作表中的数据

包括:insert、update、delete

🍉为什么update/delete一定要加where?

update和delete加where条件是为了指定操作的数据范围。如果不加where条件,会默认操作整张表的数据,可能导致大量数据被错误修改或删除


③ DQL(Data Query Language)

是 数据查询语言,最常用的命令是select

用于 查询指定字段、筛选数据以及 进行排序、分组统计等操作


④ DCL(Data Control Language)

是 数据控制语言。主要用于管理数据库用户的权限,

常见命令有 grant用于授权,revoke用于撤销权限


3. 增删改查(CRUD)

#### 英文 #### 中文 #### SQL
#### Create #### 创建 #### INSERT
#### Read #### 读取 #### SELECT
#### Update #### 更新 #### UPDATE
#### Delete #### 删除 #### DELETE

🍉什么是CRUD?

CRUD是数据库中最基本的数据操作,包括创建、查询、修改、删除,

对应SQL中的 insert、select、update、delete。


4. SELECT查询执行顺序(重点)

先找表(from),再过滤(where),再分组(group by),

再过滤组(having),再选字段(select),

再排序(order by),再分页(limit)

java 复制代码
select name, count(*)       
-- 选择最终要返回的字段,并使用count(*)统计数量

from user                 
-- 从user表中获取数据(确定数据来源)

where age > 18            
-- 过滤原始数据,只保留年龄大于18的数据

group by name             
-- 根据name字段进行分组

having count(*) > 5       
-- 对分组后的结果进行过滤,只保留数量大于5的组

order by count(*) desc    
-- 按统计数量进行降序排序(从大到小)

limit 10;                 
-- 最后只返回10条数据(分页)

5. Where和Having区别(面试常问)

where 和 having都是用于 过滤数据,区别在于

where过滤的是原始数据,在group by之前执行

having过滤的是分组后的结果,在group by之后执行。

where不能使用聚合函数,而having可以结合count、max、min等聚合函数。


6. GROUP BY是什么?⭐⭐⭐

对查询结果进行分组统计

例如:

统计每个城市用户数量。

user表:

name city
张三 上海
李四 上海
王五 北京

分组结果:

city count
上海 2
北京 1

GROUP BY通常和聚合函数一起使用,例如:

count()、sum()、avg()、max()、min()


7. JOIN是什么?⭐⭐⭐⭐

用于多张表之间进行关联查询。常见JOIN类型有

inner join(内连接)

只返回两个表都有的数据

left join(左连接)

返回左表全部数据,以及右表匹配数据


Day 2:MySQL索引 ⭐

1. 什么是索引?(必背)

索引是一种帮助数据库快速查询数据的数据结构,主要用于提高数据库的查询效率,减少全表扫描

2. 为什么需要索引?

当数据量较大时,如果没有索引,数据库需要进行全表扫描,查询效率较低;

使用索引可以快速定位数据,提高查询效率。

3. 索引的底层结构是什么?⭐⭐⭐⭐

MySQL InnoDB存储引擎默认使用B+Tree作为索引结构。

🍉为什么使用B+Tree?

查询效率稳定、支持范围查询、树高度较低

4. 为什么不用二叉树?为什么不用Hash索引?⭐⭐⭐⭐

普通二叉树

如果使用普通二叉树、数据在有序的情况下、可能退化成链表。

时间复杂度变成O(n)、效率下降

Hash索引

优点:等值查询快。

缺点:

①不支持范围查询

②不支持排序


5. B+Tree是什么?⭐⭐⭐⭐⭐

B+Tree是一种多叉平衡搜索树,MySQL利用它来组织索引数据。

特点:

① 多叉:

一个节点可以存储多个关键字、因此树的高度比较低,可以减少磁盘I/O次数

② 所有数据存储在叶子节点

③ 叶子节点通过链表连接:方便范围查询


6. 索引的优缺点 ⭐⭐⭐⭐

优点:

① 提高查询效率,减少扫描数据。

② 提高排序效率

缺点:

① 占用额外空间,因为索引本身需要存储。

② 降低 增删改 效率,因为修改数据时,需要同时维护索引


7. 什么字段适合建立索引?⭐⭐⭐⭐

① 经常作为查询条件

② 经常排序

③ 经常用于JOIN查询

🍉什么字段不适合?

① 区分度比较低、重复值很多的字段

② 经常修改的字段

因为维护成本高。

8、为什么B+Tree特别适合范围查询?

做范围查询时,可以先通过B+Tree快速定位到范围起点,比如100,然后从这个叶子节点开始,沿着链表顺序向后扫描,直到200为止,所以范围查询效率比较高

9、那B+Tree和B树相比,有什么区别?为什么数据库更喜欢B+Tree?

B树的非叶子节点也可以存储数据;

而B+树的数据集中在叶子节点,非叶子节点主要用于索引。

这样B+树的非叶子节点可以容纳更多索引项,使树的高度更低;

同时B+树的叶子节点有序连接,因此更适合范围查询


Day 3:MySQL 索引进阶 🔥

1. 什么是聚簇索引?🔥🔥🔥

①聚簇索引是数据和索引存储在一起的索引。

②比如在InnoDB中,聚簇索引的叶子节点 存储完整的数据行

通常主键索引就是聚簇索引

2. 什么是二级索引?🔥🔥🔥

又叫:

非聚簇索引 / Secondary Index

二级索引的叶子节点一般不存完整数据行,而是存 索引字段 + 主键值

3. 什么是回表?什么是覆盖索引?🔥🔥🔥(高频)

回表是指通过二级索引查询时,其中没有查询所需要的全部字段,

就需要先通过二级索引找到主键值,再根据主键到聚簇索引中查询完整数据,

这个过程叫回表。

查询所需要的字段全部能够从索引中直接获得,

不需要再回表查询,这种情况叫覆盖索引

4. 什么是联合索引?什么是最左匹配原则?🔥🔥🔥🔥

联合索引:同时基于多个字段建立的索引

查询条件要尽量从联合索引 最左边的字段开始匹配。

遇到范围查询后,范围字段可以使用索引,但其后的字段通常不能继续用于缩小索引扫描范围

5. 哪些情况可能导致索引失效?🔥🔥🔥🔥(高频)

① 违反联合索引最左匹配

② 对索引列进行函数操作

③ 对索引列进行计算

④ LIKE 以 % 开头

6. 为什么不建议 select * ?🔥🔥

①可能增加不必要的数据读取

②并可能导致无法利用覆盖索引

③增加回表查询成本

7、为什么①通常可以正常利用索引,而②对索引列使用函数后可能无法正常利用这个索引?

java 复制代码
① where name = 'Felix';

② where lower(name) = 'felix';

索引存的是原始值的有序结构,但查询条件用的是计算后的值,

因此数据库可能无法直接根据原索引定位数据

%:开头确定,知道从哪找。

%:开头不确定,不知道从哪找。

java 复制代码
where name = 'Felix'
and age = 20
and city > '上海';

最左匹配:

①中间缺字段会断;

②遇到范围查询,范围列能用,但后面的列不能继续用于缩小联合索引的扫描范围。


Day 4:MySQL 事务篇 🧩

1. 什么是事务?💎为什么需要事务?🔷

事务是一组数据库操作的集合,这些操作要么全部成功,要么全部失败,用来保证数据的 一致性和可靠性

(防止执行过程中出现异常导致数据处于错误状态)

3. 事务MySQL中怎么使用?🔷

sql 复制代码
start transaction
开始事务

commit
提交事务

rollback
回滚事务

4. 什么是 ACID?💎💎

事务有四大特性:

原子性:Atomicity

一个事务中的操作要么全部成功,要么全部失败。

一致性:Consistency

事务执行前后,数据都应该保持合法、一致的状态(总金额)

隔离性:Isolation

多个事务并发执行时,事务之间应该尽量互不干扰

持久性:Durability

事务一旦commit提交成功,修改的数据就应该被持久保存。

5. 并发事务会出现什么问题?💎💎

① 脏读 💎

一个事务读到了另一个事务还没有提交的数据。

②不可重复读 💎

同一个事务中,对同一条数据读取两次,结果不一样。

③幻读 💎

在同一个事务中,使用相同的查询条件进行多次查询,得到的记录集合不一致。

6. MySQL事务隔离级别 💎💎

#### 隔离级别 #### 中文 #### 简单理解
#### Read Uncommitted #### 读未提交 #### 别人没提交我也能读
#### Read Committed #### 读已提交 #### 只能读别人已提交的数据
#### Repeatable Read #### 可重复读 #### 同一事务中重复读取保持一致
#### Serializable #### 串行化 #### 事务高度串行执行

7. MySQL InnoDB 默认隔离级别 💎💎

InnoDB 默认事务隔离级别是 Repeatable Read(RR,可重复读)

8. 四种隔离级别解决什么问题?💎

#### 隔离级别 #### 脏读 #### 不可重复读 #### 幻读
#### Read Uncommitted #### ❌ #### 可能 #### ❌ #### 可能 #### ❌ #### 可能
#### Read Committed #### ✅ #### 解决 #### ❌ #### 可能 #### ❌ #### 可能
#### Repeatable Read #### ✅ #### 解决 #### ✅ #### 解决 #### ⚠️标准定义下仍需关注幻读;InnoDB有额外机制处理许多幻读场景
#### Serializable #### ✅ #### ✅ #### ✅

Day 5:MVCC + MySQL 锁 🛡️

1、什么是 MVCC?🔥🔥🔥

Multi-Version Concurrency Control,多版本并发控制。

MVCC是一种并发控制机制,

一条数据维护多个版本,让不同事务读取适合自己的版本,提高并发性能

2 、为什么需要 MVCC?🔥🔥🔥

你改你的新版本,我读我的旧版本,大家尽量别互相等。

3、undo log的两大作用:

undo log

①是回滚日志,主要用于事务回滚。

②帮助构建历史版本链。

MVCC 可以基于这些版本链,让不同事务读取自己想要的版本。

4、Read View

Read View 相当于一套可见性规则,用来判断版本链中的哪些数据版本能被当前事务读取

🍉为什么 InnoDB 的 Repeatable Read(可重复读)能够解决不可重复读问题?请从undo log、MVCC、版本链和 Read View 的角度解释。

undo log 记录数据修改前的相关信息,帮助构建版本链。Read View 是一套可见性规则,用于判断版本链中哪些数据能被当前事务读取。

RR 下同一个事务会保持一致的Read View,所以即使其他事务修改并提交了数据,我还是可以读取之前对我可见的版本,从而实现可重复读。

5、什么是快照读和当前读?🔥🔥🔥

快照读读取的是 MVCC 中对当前事务可见的数据版本;

当前读读取的是当前最新的数据,通常需要加锁。

6、什么是共享锁和排他锁?

共享锁(Shared Lock,S锁)

允许多个事务同时读取同一份数据,但会限制其他事务对该数据进行修改

排他锁(Exclusive Lock,X锁)

加了X锁后,其他事务不能再获取其它S锁或X锁,需要等待当前事务释放锁。

表锁 vs 行锁

表锁是锁住整张表,锁粒度比较大,并发性能相对低;

行锁是锁定具体的 索引记录,锁粒度更小,并发性能更好。

(锁粒度 = 锁的范围大小)

记录锁(Record Lock)vs 间隙锁(Gap Lock)

Record Lock:锁住某一条具体的索引记录。

Gap Lock: 锁住两条索引记录之间的间隙

为啥(临键锁) Next-Key Lock 能帮助防止幻读?🔥🔥🔥🔥

Next-Key Lock 是 Record Lock 和 Gap Lock 的结合。

它既可以锁住已有的索引记录,又可以锁住记录之间的间隙,从而阻止其他事务在相应范围内插入新的记录,因此可以帮助防止幻读。

7、InnoDB 在 RR 隔离级别下,是怎么处理幻读问题的?

InnoDB 在 RR 隔离级别下主要通过 MVCC 和 锁机制 处理幻读场景。

①对于普通快照读,通过 MVCC、版本链和 Read View 保持 数据的一致

②对于当前读,则通过 Gap Lock、Next-Key Lock 等锁机制锁住相应的索引范围和间隙,防止其他事务插入新的记录,从而处理幻读问题。

8、为什么说 InnoDB 的查询条件如果没有合适的索引,可能导致"锁范围扩大",甚至表现得像锁表?

如果查询条件没有合适的索引,可能需要进行全表扫描,并锁住大量扫描到的索引记录,导致锁范围扩大,影响并发性能。

🍉什么情况下行锁可能退化成类似"锁表"的效果?

查询/更新条件中的字段没有合适的索引。

🍉快照读 && 当前读

普通 SELECT 一般属于快照读,通过 MVCC 和 Read View 读取当前事务可见的数据版本;

SELECT ... FOR UPDATE 属于当前读,会读取最新的数据版本,并对相关记录加锁。

9、为什么 SELECT ... FOR UPDATE 不能像普通 SELECT 一样只读取历史快照,而要读取当前最新的数据并加锁?

因为 SELECT ... FOR UPDATE 通常是为了后续修改数据,所以需要读取当前最新的数据,并对相关记录加锁,防止其他事务同时进行冲突修改。

🍉事务 A COMMIT 之后,事务 B 会发生什么?

COMMIT 不仅提交事务的数据修改,还会释放该事务持有的锁。

🍉如果事务 A 还是持有 X Lock,但事务 B 执行select

事务 B 会不会被阻塞?为什么?

事务 B 通常不会被阻塞,因为普通 SELECT 属于快照读,它通过 MVCC,根据 Read View 的可见性规则,从版本链中读取当前事务可见的数据版本。


Day6:SQL 优化与 EXPLAIN 🔥🔥🔥🔥

第一题 🔥🔥🔥:什么是慢 SQL?

慢 SQL(执行时间较长、执行效率较低的 SQL) → 慢查询日志定位具体SQL → EXPLAIN 分析执行计划 → 重点看四个字段 → 针对性优化

(比如建立或调整合适的索引、优化联合索引、避免索引失效、减少 SELECT *、优化深分页等。优化之后再重新通过 EXPLAIN 和实际执行情况验证优化效果。)

第二题 🔥🔥🔥🔥:EXPLAIN 是干什么的?

MySQL 打算怎么执行这条 SQL?

type → 怎么找数据的?

key → 本次执行实际使用的索引

rows → 预计 扫描的行数

Extra → 还有什么额外执行信息?

第三题 🔥🔥🔥🔥:

type = ALL:扫描整张表

type = index:MySQL 需要扫描整棵索引

type = range:只扫描符合条件的一段索引范围,而不是扫描整棵索引

type = ref:通过普通索引进行等值匹配,可能匹配到多条记录

type = const:通过主键索引或唯一索引进行等值查询,并且最多只匹配一条记录

🔥 一般至少希望查询达到 range 级别,最好能达到 ref;

出现 index、ALL 时需要重点关注,但不是看到 ALL 就一定有问题。

为什么不能看到 key != NULL、SQL 使用了索引,就直接判断"这条 SQL 性能很好"?

结合rows

为什么 Extra = Using index 通常是一个比较好的信号?

Using index → 使用了覆盖索引 ⭐

Using where → 还需要根据 WHERE 条件进行过滤

Using filesort→ 需要额外进行排序 🚨

Using temporary→ 使用了临时表 🚨

第四题:SQL优化---深分页

sql 复制代码
SELECT *
FROM orders
ORDER BY id
LIMIT 1000000, 10;

LIMIT offset, size 在 offset 很大时会产生深分页问题,因为数据库需要扫描并丢弃前面大量数据,最终只返回少量记录,造成不必要的扫描开销。

优化后:

sql 复制代码
SELECT *
FROM orders
WHERE id > 1000000  !!!
ORDER BY id
LIMIT 10;

Day7:InnoDB 底层 + MySQL 日志体系

1、什么是 Buffer Pool?InnoDB 为什么需要 Buffer Pool?

Buffer Pool 是 InnoDB 在 内存 中的缓冲区域,

用于缓存数据页等内容,减少磁盘 I/O,提高数据库性能。

2、是不是每执行一次 UPDATE,MySQL 都要立刻把修改后的数据写回磁盘?

InnoDB 更新数据时,通常先修改 Buffer Pool,并记录 redo log,之后再把脏页刷回磁盘,而不是每次 UPDATE 都立即写磁盘。

① 脏页

这种已经被修改、但还没有刷回磁盘的数据页,叫脏页。

② redo log

记录"这次修改做了什么",用于在数据库异常恢复时重新执行这些修改。

3、既然有了 redo log,为什么还需要 binlog?redo log 和 binlog 有什么区别?

redo log 主要用于 InnoDB 的崩溃恢复;

binlog 主要用于 主从复制 和 数据恢复

redo log 是 InnoDB 的日志,而 binlog 是 MySQL Server 层面的日志,

因此 MySQL 需要同时维护这两套日志。

4、为什么 MySQL 需要两阶段提交?

MySQL 使用两阶段提交,是为了保证 redo log 和 binlog 的一致性,避免出现一个日志已经记录事务提交、另一个日志却没有记录的情况。

5、redo log 为什么叫"循环写"? binlog叫"追加写"?

redo log 空间有限,通过循环写实现空间复用。

而 binlog 需要记录数据库的历史变更,用于主从复制和数据恢复,因此通常采用追加写的方式保存日志。

6、一个update的背后流程图

sql 复制代码
             UPDATE
                ↓
        ┌──────────────┐
        │ Buffer Pool  │
        │ 修改数据页    │
        └──────┬───────┘
               ↓
             脏页
               │
        ┌──────┴──────┐
        ↓             ↓
    redo log        binlog
   崩溃恢复        复制/恢复
        ↘           ↙
         两阶段提交
        保证日志一致
              ↓
       后续脏页刷盘
相关推荐
胖头鱼的鱼缸(尹海文)32 分钟前
胖头鱼的技术专栏-465 数据库能力上移还是下沉:库变弱了,应用就变重了(20260828)
数据库
2601_962181961 小时前
Redis Redis介绍、安装 - Redis客户端
数据库·redis·postman
2601_962062942 小时前
Spring Boot入门——Spring Boot项目的创建
java·数据库·spring boot
冰暮流星2 小时前
mysql之外键约束
数据库·mysql
茶栀(*´I`*)2 小时前
数据库零基础入门指南:从基本概念到 SQL 实战
数据库·sql
ERD Online2 小时前
Cursor 连上 MCP:读一张 ER 图,提交一版建议
数据库·后端·开源·cursor·mcp
foolishlee2 小时前
openGauss postmaster退出流程
数据库
叫我:松哥2 小时前
基于flask仿小米商城管理系统,使用flask开的一个商场网站
数据库·后端·python·flask
子非鱼a3 小时前
【WEB】[BJDCTF2020]Easy MD5
数据库