大家好我是小明,今天复习mysql



1.慢查询如何分析

可以使用EXPLAIN或者DESC命令获取MYSQL如何执行的信息。
在这里插入图片描述

这里比较重要的字段是下面几个

  • type 这条sql连接类型,性能好到差(NULL, system, const,eq_ref, range, index, all)
  • possible_keys 当前可能命中的索引
  • key 实际命中的索引
  • key_len占用索引大小
  • Extre 额外的建议优化
    在这里插入图片描述
    在这里插入图片描述
    面试回答:
    在这里插入图片描述

2.Mysql索引

定义:索引是数据库中一种特殊的数据结构,它通过对表中一个或多个字段进行排序存储,来加速查询时的数据定位,本质是用空间换时间的优化手段。

Mysql索引底层默认使用的是B+树,再聊B+树之前,我们先看一下二叉树和B树。
大家都知道二叉搜索树
在这里插入图片描述
左边的数字一定比右边的大
但是最坏的情况是这样的
在这里插入图片描述
红黑树:可以理解为近似平衡的二叉搜索树,
近似平衡(最长路径 ≤ 2 倍最短路径)
在这里插入图片描述
AVL树是高度平衡的树
即:左右子树高度差(平衡因子)的绝对值 ≤ 1

这时候树是平衡了,查找的效率高啦,但是如果拥有海量的数据,树的高度还是非常高

B树

B 树是一种多路平衡查找树,它的节点可以拥有多个子节点(不像二叉树只有 2 个)
在这里插入图片描述
二叉树的问题:如果数据量很大(比如 1000 万条),二叉树的高度会很高(约 20-30 层)。每查一层就要读一次磁盘,查 30 次磁盘太慢了!
B 树的优势:因为一个节点能存很多数据(比如 1KB~16KB),树变得很 “矮胖”。查 1000 万条数据,可能只需要读 3~4 次磁盘。

结论:树的高度越低,磁盘 I/O 次数越少,查询越快。

B+树
在这里插入图片描述

  • B+树磁盘读写代价更低: B+树在叶子节点存储数据,非叶子节点存储指针,相比于B树查找节点的时候会缓存路径上的节点,磁盘读写代价大。
  • 查询效率B+树更加稳定:B+树只在叶子节点存储数据,非叶子节点存储指针。查询都是logn。
  • B+树便于扫盘和区间查询: 原因叶子节点使用双向链表连接。

3.聚簇索引和非聚簇索引(回表查询)

在这里插入图片描述
聚簇索引:一张表只能有 1 个,一般是主键,无主键时会选唯一非空索引,数据和索引存储在一起,叶子节点直接存完整数据行。
非聚簇索引: 索引与数据分开存储,叶子节点存的是主键值(需要回表查询数据)。

回表查询
在这里插入图片描述
Where name = “Arm”命中非二级索引,在二级中找到Arm,Arm节点存储的是主键,在根据主键查询完整用户。


4.覆盖索引(MySQL超大分页)

在这里插入图片描述
MySQL超大分页

在这里插入图片描述
优化:
在这里插入图片描述


5. 索引失效

① 违反最左前缀法则(前提是使用复合索引)
在这里插入图片描述
在这里插入图片描述

② 范围查询右边的列,不能使用索引
在这里插入图片描述

范围查询之后的索引失效

③ 不要在索引列上进行运算操作,索引将失效
在这里插入图片描述

④ 字符串不加单引号,造成索引失效。(类型转换)
在这里插入图片描述

⑤ 以 % 开头的 Like 模糊查询,索引失效
在这里插入图片描述

这里直接背就好啦


5.1 索引的创建原则

  1. 针对于数据量较大,且查询比较频繁的表建立索引。单表超过 10 万数据(增加用户体验)
  2. 针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引。
  3. 尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高。
  4. 如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引。
  5. 尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间,避免回表,提高查询效率。

6.事务

事务:数据库中一组不可分割的数据库操作(SQL 语句集合),这组操作要么全部执行成功,要么全部执行失败回滚,它是数据库保证数据一致性和完整性的核心机制。

6.1 事务的特性(ACID)

  • 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
  • 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
  • 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
  • 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。

最好是结合实际场景解释给面试官

在这里插入图片描述

  1. 原子性:转账要么失败要么成功
  2. 一致性:转账一个人得到钱一个失去钱,保持数据一致性
  3. 隔离性:转账过程不受第三方打扰
  4. 持久性:转账成功后数据修改是持久化的

6.2 并发事务问题,隔离级别

== 并发事务问题==
在这里插入图片描述
怎么解决呢?

事务的隔离级别
在这里插入图片描述

mysql默认的事务级别是可重复读,事务的隔离级别越高,数据越安全,但是性能比较低。


7. uodo log 和redo log 区别

  1. undo log(回滚日志)

它记录的是数据修改前的状态。

你执行 INSERT / UPDATE / DELETE 时,数据库会先把「修改前的值」写入 undo log。

用来支持:

  • 事务回滚时,用 undo log 把数据恢复到修改前的状态
  • 多版本并发控制(MVCC)
  1. redo log(重做日志)

它记录的是数据修改后的状态(物理日志)。

当你修改数据时,数据库会把 “要修改成什么” 写入 redo log,并立即刷盘。

用来支持:

  • 录的是数据页的物理变化,服务宕机可用来同步数据
  • 保证事务提交后不会丢数据(持久性)

8. 分库分表

前提:项目业务数据逐渐增多,或者业务发展比较迅猛,优化已经解决不了问题;
在这里插入图片描述

**垂直拆分:**以表为依据,根据业务将不同表拆分到不同库中。

  1. 垂直拆库
    在这里插入图片描述
    特点:按照数据分级管理。

  2. 垂直拆表
    在这里插入图片描述
    把一张表的字段拆分为不同的表,两张表可以在不同库中,也可以在同一个库中。

好处:

  • 冷热数据分离
  • 减少IO过度争抢,两表互不影响。
  1. 水平分库

将一个库中的树拆分到多个库中。

在这里插入图片描述

好处:

  • 解决单库数据量太大,提高系统高并发。
  1. 水平分表

将一个表的数据拆分到多个表中(可以在同一个库里面)

在这里插入图片描述
好处:

  • 优化单一表数据量过大产生性能问题
  • 避免IO争抢;

分库分表的问题

  • 分布式事务一致性问题
  • 跨界点关联查询
  • 跨界点分页,排序函数
  • 主键重复

解决方案

加中间件:MyCat
在这里插入图片描述

面试回答参考:
在这里插入图片描述


好了今天就到这里

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐