MySQL学习笔记

1. MySQL中,如何定位慢查询?

  • 慢查询就是接口响应时间比较长。如果是 SQL 的问题,就要去定位这些 SQL。
  • 第一种方式:MySQL 中提供了慢查询日志的功能。可以在 MySQL 配置文件中开启慢查询日志,设置 SQL 执行超过多少秒,就记录到慢查询日志中。
  • 第二种方式:可以借助一些运维工具:如 Skywalking 和 Prometheus 。图形化的界面比较直观,可以看到是哪个接口比较慢,SQL 的执行时间,定位是哪个 SQL 出了问题。

2. 定位到慢查询后,如何优化呢?

  • 通过 explain 命令查看 SQL 的执行计划。
    • 可以通过 key 和 key_len 看有没有用到索引,判断索引是否失效。
    • 可以通过 type 属性查看 SQL 的执行效率,看下是否走了全表扫描,如果 type 属性是 all 的话,可以加索引。
    • 可以通过 extra 属性判断是否出现了回表,如果出现了,可以加索引。
      在这里插入图片描述

3. 什么是索引?

  • 索引是一种用来高效查询数据的有序的数据结构,索引的作用相当于书的目录。
  • 没有使用索引查询就比较慢,因为没有用到索引走的是全表扫描,查一条数据从表的第一行开始遍历,遍历到最后一行,效率就比较低。
  • 用了索引,就会形成一个索引的数据结构,底层是 B+树,效率比较高。
  • 但是使用索引也会带来一些问题,所以索引不是越多越好的。使用索引会占用一定的磁盘空间,虽然使用索引让查询变快了,但是对增删改的效率会有影响。

3.1 索引的底层数据结构了解过嘛?

MySQL 默认的存储引擎 InnoDB 采用的是 B+ 树 作为索引。

为什么使用B+树?

  • 选择 B+ 树的主要原因是:
    • B+ 树查询磁盘 I/O 次数更少,非叶子节点只存储索引,叶子节点存储数据。
    • B+ 树支持范围查询,叶子节点是一个双向链表。

为什么不选择二叉树?

  • 有一种特殊的二叉树,叫二叉查找树,它有一个特点:父节点左边的都比它小,右边的都比它大,可能会出现单支树的情况,只有左子树或者只有右子树,这时候二叉树就退化成链表了,查询的时候又变成了全表扫描。所以为了避免这种情况的发生,后面就有了平衡二叉树。

为什么不选择平衡二叉树?

平衡二叉树本身是二叉查找树,左右子树高度绝对值之差不超过1,就是为了避免退化成链表的情况。但是平衡二叉树每个节点只存放一个数据,B+ 树可以存放更多的数据,树高也更低,磁盘 I/O 的次数更少,所以B+树更合适。

3.2 B+ 树和 B 树的区别?

  • B+ 树是对 B 树的升级。B+ 树与 B 树的区别,主要是以下这几点:
  • B+ 树非叶子节点存放索引,这些索引也会同时会出现在叶子节点中,并且叶子节点会存放实际的数据,叶子节点之间构成一个有序链表。
  • B+ 树查询磁盘 I/O次数更少。B+ 树的非叶子节点不存放数据,仅存放索引,因此相比 B 树,B+ 树的非叶子节点可以存放更多的索引,因此 B+ 树可以比 B 树更矮胖。
  • B+ 树插入和删除效率更高。B+ 树删除一个节点的时候,可以直接从叶子节点中删除。
  • B+ 树支持范围查询。比如我们想知道 12 月 1 日和 12 月 12 日之间的订单,这个时候可以先查找到 12 月 1 日所在的叶子节点,然后利用链表向右遍历,直到找到 12 月12 日的节点。
  • MySQL 中索引的数据结构就是采用了 B+ 树,B+ 树结构如下图:在这里插入图片描述

4. 什么是聚簇索引(聚集索引)和非聚簇索引(二级索引)?

  • 聚集索引 (Clustered Index):叶子节点保存行数据。一般主键索引就是聚集索引。
  • 二级索引 (Secondary Index):叶子节点关联的是对应的主键值。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

4.1 什么是回表查询?

  • 先到二级索引中查找数据,找到主键值,然后再到聚集索引中根据主键值,最终拿到这一行的数据。在这里插入图片描述

4.2 索引有哪些?

  • 主键索引:主键默认就是主键索引,一个表只能有一个主键。
  • 唯一索引 (UNIQUE):数据列不可以重复,一个表可以多个列创建唯一主键。
  • 普通索引 (INDEX)
  • 单列索引:一个索引只包含单个列。
  • 联合索引:一个索引包含了多个列。
  • 聚集索引 (Clustered Index):叶子节点保存行数据。
  • 二级索引 (Secondary Index):叶子节点关联的是对应的主键。
    在这里插入图片描述

5. 什么是覆盖索引?

覆盖索引是指 select 查询语句中使用了索引,查询的列必须在索引中要能找得到。如果查询的有的列没有索引,就会出现回表查询。所以一般查什么就 select 什么,不要使用select *。
在这里插入图片描述

5.1 MySQL 超大分页怎么处理?

超大分页就是数据量比较大的时候作分页。因为 limit 分页查询,要对数据做排序,效率会比较低。我们可以用覆盖索引和子查询来作超大分页。

  • 先用覆盖索引,查 id
  • 再用子查询,通过 id 来过滤
    在这里插入图片描述

6. 创建索引需要注意什么?

  • 对数据和查询量比较大的表建索引。
  • 建索引的列,是查询比较频繁的字段,一般是对 order by, group by 、where 操作的字段建索引。
  • 尽量使用联合索引,减少单列索引,避免回表。
  • 索引也不能建太多,索引越多,维护索引的成本就越大。对磁盘占用、虽然提高了查询效率,但是对增删改效率有影响。

7. 什么情况下索引会失效?(使用索引需要注意什么? 答:要避免出现索引失效的情况)

  • 使用索引要遵守 最左前缀法则。最左前缀法则 说的是联合索引,就是最左边的列必须要存在,不能跳过其中一列,如果跳过了某一列,后面的字段索引会失效。

  • 范围查询时:联合索引中,出现 > 或者 < 的范围查询,右侧的列索引失效。

    • 如何解决:用 >= 或者 <= 。
  • 在索引列上进行函数运算操作,索引失效。

  • 对于字符串,不加引号,索引失效。

  • 模糊查询,如果是头部模糊匹配,索引失效。

  • or 连接的条件, 如果 or 前的条件中的列有索引,而后面的列中没有索引,索引失效

  • 如果使用索引比全表扫描更慢,则不使用索引。

通常情况下,想要判断这条 SQL 是否有索引失效的情况,可以使用 explain 执行计划来分析。

8. SQL 优化的经验

SQL 优化可以在这几个方面进行优化:

  • 建表的时候对表的优化。
  • 可以使用索引。
  • 对 SQL 语句的优化。
  • 可以对数据库作主从复制,读写分离。
  • 数据量比较大的时候,可以分库分表。

8.1 建表的时候,如何优化?

对字段要选择合适的类型,比如对字符串,可以根据实际情况使用 char 或者 varchar。

8.2 用索引的时候,如何优化?

参考6和7。

8.3 SQL 语句,如何优化?

  • 不要直接使用 select * ,要使用 select + 具体字段,避免回表。
  • 注意写 SQL 时索引失效的情况。

9. 什么是事务?事务的四大特性ACID是什么?

  • 事务是一组操作的集合,这些操作要么同时成功,要么同时失败。(例子:银行转账)

事务的四大特性ACID:

  • 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
  • 一致性(Consistency):事务完成时,所有的数据都保持一致状态。
  • 隔离性(Isolation):有多个并发的事务,事务A和事务B都在操作数据库,事务A和事务B在操作的时候互不干扰。
  • 持久性(Durability):事务一旦提交或回滚,数据库中的数据的改变就是永久的。
    在这里插入图片描述

10. 并发事务所引发的问题

  • 脏读:一个事务读到另外一个事务还没有提交的数据。在这里插入图片描述
  • 不可重复读:一个事务先后读取同一条记录,但两次读取的数据不一样。在这里插入图片描述
  • 幻读:一个事务查询数据时,没有查到,但是在插入数据时,又发现数据已经存在。在这里插入图片描述

10.1 怎么解决并发事务所引发的问题?(事务隔离级别)

隔离级别脏读不可重复读幻读
读未提交
读已提交×
可重复读(MySQL默认)××
串行化×××
  • 事务隔离级别越高,数据越安全,但是性能越低,一般采用默认的隔离级别。

10.2 InnoDB 有哪几类行锁?如何解决幻读?

InnoDB 支持三种行锁定方式:

  • 记录锁(Record Lock):锁一整行记录。
  • 间隙锁(Gap Lock):锁定一个范围,不包括记录本身。
  • 临键锁(Next-Key Lock):Record Lock+Gap Lock,锁定一个范围,包含记录本身,主要目的是为了解决幻读问题。记录锁只能锁住已经存在的记录,为了避免插入新记录,需要依赖间隙锁。也就是说执行 insert 操作的时候需要依赖 Next-Key Lock 临键锁(Record Lock+Gap Lock) 进行加锁来保证不出现幻读。

如何解决幻读?

举个例子:执行 delete 和 update 操作的时候,可以直接对记录加锁,保证事务安全。而执行 insert 操作的时候,由于记录锁(Record Lock)只能锁住已经存在的记录,为了避免插入新记录,需要依赖间隙锁(Gap Lock)。也就是说执行 insert 操作的时候需要依赖 Next-Key Lock 临键锁(Record Lock+Gap Lock) 进行加锁来保证不出现幻读。

11. 三大日志,解决事务什么问题?

MySQL 里面的三大日志是 binlog、 undolog、redolog。

  • binlog (二进制日志),主要用于数据备份和主从复制,保证事务的一致性。
  • undo log (回滚日志),记录的是数据的历史版本信息,相当于一个快照,保证事务的原子性。主要用于事务回滚和 MVCC。
  • redo log (重做日志) 用于故障恢复的时候恢复数据,保证的是事务的持久性。
    在这里插入图片描述

12. 什么是 MVCC,用来做什么?(事务的隔离性是如何保证的?)

  • MVCC 是多版本并发控制,主要是用来提高数据库的读写性能。让数据库在读写的时候不用去加锁。
  • MVCC处理的是快照读。有2个概念,一个是快照读,一个是当前读。
    • 快照读就是简单的 select 语句,读取的是数据的历史版本信息。
    • 当前读指的是悲观锁,每次读取数据的时候都要加锁。
  • MVCC 底层是由三部分组成,隐藏字段,undolog 和 readview。
    • 隐藏字段:用于不可见的字段,比如事务的id,回滚的指针。
      在这里插入图片描述

    • undolog:执行增删改操作时候产生的方便回滚的日志。
      在这里插入图片描述

    • readview(读视图):有了 readview ,在访问某条记录时,根据可见性算法,判断事务能不能访问这条数据。在这里插入图片描述

在这里插入图片描述

13. MySQL 主从同步原理

MySQL 主从复制的核心就是 binlog 二进制日志,记录了创建表的那些语句和增删改的那些语句,但不包括查询语句。有了 binlog 后,同步数据就方便多了,主库负责写,从库负责读。
具体的同步流程是这样的:

  • 第一:主库的数据发生变化时,就会将变化的数据记录在 binlog 中。
  • 第二:从库 到主库的 binlog 文件中读取数据 ,写入到从库的中继日志 Relay Log 中 。
  • 第三:从库 再去读取这个中继日志的文件,重新执行一下里面的命令,执行完毕之后,主库和从库的数据就同步了。
    在这里插入图片描述

14. MySQL 的分库分表

如果数据量比较大的话,可以考虑分库分表。分库分表又可以分为垂直拆分和水平拆分。

  • 在微服务开发中,每个微服务对应了一个数据库,是根据业务进行拆分的,这个其实就是垂直拆分。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

15. InnoDB 存储引擎与 MyISAM 的区别 ?

  • MySQL 5.5 之后,InnoDB 是默认的存储引擎。
  • InnoDB 引擎, 支持事务, 而 MyISAM 不支持。
  • InnoDB 引擎, 支持行锁和表锁, 而 MyISAM 仅支持表锁, 不支持行锁。
  • InnoDB 引擎, 支持外键, 而 MyISAM 是不支持的。

16. 三大范式是什么?

  • 第一范式:每列不可拆分,保持原子性。
  • 第二范式:在第一范式基础上增加了主键,保证唯一性。
  • 第三范式:在第二范式基础上增加了外键。比如在设计订单表时,可以将客户 id 作为一个外键和订单表建立联系。
  • 三大范式的作用是为了控制数据库的冗余,是对空间的节省,实际上,一般互联网公司的设计都是反范式的,通过冗余一些数据,避免跨表跨库,利用空间换时间,提高性能。

17. MySQL 执行一条更新语句是怎么执行的?

在这里插入图片描述
执行一条更新语句时,需要将数据写入表中,还要记录相应的日志。这里涉及到两阶段提交。

  • 在对 redolog 写入时有两个阶段的提交,一是 binlog 写入之前 prepare 状态的写入,二是 binlog 写入之后 commit 状态的写入。
  • redolog 和 binlog 都可以用于表示事务的提交状态,而两阶段提交就是让这两个状态保持逻辑上的一致。
    在这里插入图片描述

18. 什么是 ER 图?

ER 图 描述了实体以及实体之间的关系。下图是一个学生选课的 ER 图,每个学生可以选若干门课程,同一门课程也可以被若干人选择,所以它们之间的关系是多对多(M: N)。另外,还有其他两种实体之间的关系是:1 对 1(1:1)、1 对多(1: N)。
学生与课程之间联系的E-R图

19. 数据库设计通常分为哪几步?

  1. 需求分析 : 明确需求,要几张表。
  2. 概念结构设计 : 画 E-R 图。
  3. 逻辑结构设计 : 将 E-R 图转换成表。
  4. 物理结构设计 : 为数据库选择合适的存储引擎。
  5. 数据库实施 : 编程和测试。
  6. 数据库的运行和维护

20. MySQL 的内连接、外连接有什么区别?

MySQL 的连接主要分为内连接和外连接,外连接分为左外连接、右外连接。

在这里插入图片描述
在这里插入图片描述

21. char 与 varchar 的区别?

  • char表示定长字符串,长度不可变。
  • varchar表示不定长字符串,长度可变。
  • 根据实际需要,对于长度固定的字符串,使用 char,对于长度不确定的,使用 varchar。

22. MySQL 怎么存储 emoji😊?

  • MySQL 可以用字符串来存储 emoji,这里涉及到2种编码: utf8utf8mb4 。需要使用 utf8mb4 编码。
  • utf8:只能存1-3字节,emoji 是占4字节。
  • utf8mb4: utf8 的升级,可以存4个字节。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值