【MySQL】学习笔记

SQL语句执行顺序

  • 案例

    首先,我们先看下如上SQL的执行顺序,如下:

1.首先执行 FROM 子句, 从学生成绩表中组装数据源的数据。
2.执行 WHERE 子句, 筛选学生成绩表中所有学生的数学成绩不为 NULL 的数据 。
3.执行 GROUP BY 子句, 把学生成绩表按 “班级” 字段进行分组。

4.计算 avg 聚合函数, 按找每个班级分组求出 数学平均成绩。
5.执行HAVING子句, 筛选出班级 数学平均成绩大于 75 分的。

6.执行SELECT语句,返回数据,但别着急,还需要执行后面几个步骤。
7.执行 ORDER BY 子句, 把最后的结果按 “数学平均成绩” 进行排序。
8.执行LIMIT ,限制仅返回3条数据。结合ORDER BY 子句,即返回所有班级中数学平均成绩的前三的班级及其数学平均成绩。

SQL一些容易遇到的问题

  1. 可以先通过where 过滤,再进行分组
  2. 聚合函数 出现在select 或者 having
  3. group by 可以有多个字段
  4. on 是首要筛选的条件,where对此进行虚表过滤。on优先级最高。
  5. having过滤条件在聚合函数之后。也就意味着可以过滤聚合函数
  6. 遇到一些不正常走索引的可以使用 force index() 来强制走索引
  7. explain 查看执行计划,
  8. show profiles 查慢查询日志(set profiling = 1;set long_query_time = 0; )

一条SQL是如何执行的


MyIsam 与 Innodb 区别

  • MyIsam 不支持事务不支持行锁
  • MyIsam 表的行数都会自己做存储(查MyIsam 表的行数的时候,会比较快)
  • innodb 主键索引存储整行的数据;其他二级索引存储【索引数据与主键ID】
  • Innodb 的二级索引 存的是【索引数据与主键ID】,通过主键索引来查询到这个行数据

更新操作详解

1.更新之前会先进行查询
2.拿到行数据之后,用执行器调用存储引擎的接口,进行更新操作。
3.更新的操作会设计一些日志WAL

Write Ahead Log简称WAL,在分布式存储系统中的元数据更新中应用得十分广泛。WAL的主要意思是说在将元数据变更操作写入到持久稳定的db之前,先预先写入到一个log中,然后再由另外的操作将log apply到外部的持久db里去。这种模式会减少掉每次的db写入操作,尤其当系统要处理大量的transaction操作的时候,WAL的方式相比较于实时同步db的方式有着更高的效率

日志分类

redo log

  • 空间有限,只有4G
    在这里插入图片描述

在这里插入图片描述

bin log

  • 不是环形的
  • 磁盘上的全量日志
  • 只要磁盘够大,你只管追加操作就行了

MySQL如何做到崩溃恢复

  • 奔溃提交涉及到:两阶段提交
  • 顺序:
    1.首先记录一个redo log
    2.in-> redo prepare -> out 其中一个状态崩溃了都无法恢复
  • bin log 可日志回放
    在这里插入图片描述

MySQL执行计划

  • Extra:Using index 表示走了覆盖索引,不需要回表
    在这里插入图片描述

主键索引存储结构

在这里插入图片描述

二级索引存储结构

在这里插入图片描述

联合索引存储结构

  • 比较占用空间
    在这里插入图片描述

优化案例

视频

  1. 强制走索引
  2. 走联合索引
  3. 拒绝回表,小表驱动大表(翻页)

数据库的优化,大多数都在优化IO

索引下推(ICP)

https://www.bilibili.com/video/BV12V4y157yi/?spm_id_from=333.999.0.0&vd_source=0722208728783f1453516ee9e0d6ca3f

  • 不使用ICP的情况下,在使用非主键索引(又叫普通索引或者二级索引)进行查询时,存储引擎通过索引检索到数据,然后回表,判断数据是否符合条件 。
  • 索引下推在非主键索引上的优化,可以有效减少回表的次数,大大提升了查询的效率。
  • ICP特点:先判断索引列是否满足条件,不满足则忽略。

在开始之前先先准备一张用户表(user)
其中主要几个字段有:id、name、age、address
建立联合索引(name,age)
假设有一个需求,要求匹配姓名第一个为陈的所有用户,sql语句如下:

SELECT * from user where  name like '陈%'

根据 “最佳左前缀” 的原则,这里使用了联合索引(name,age)进行了查询,性能要比全表扫描肯定要高。

问题来了,如果有其他的条件呢?
假设又有一个需求,要求匹配姓名第一个字为陈。
年龄为20岁的用户,此时的sql语句如下:

SELECT * from user where  name like '陈%' and age=20

这条sql语句应该如何执行呢?
下面对Mysql5.6之前版本和之后版本进行分析。
Mysql5.6之前的版本
5.6之前的版本是没有索引下推这个优化的,因此执行的过程如下图:

会忽略age这个字段,直接通过name进行查询,在(name,age)这课树上查找到了两个结果,id分别为2,1,然后拿着取到的id值一次次的回表查询,因此这个过程需要回表两次

Mysql5.6及之后版本
5.6版本添加了索引下推这个优化,执行的过程如下图:

InnoDB并没有忽略age这个字段,而是在索引内部就判断了age是否等于20,对于不等于20的记录直接跳过,因此在(name,age)这棵索引树中只匹配到了一个记录,此时拿着这个id去主键索引树中回表查询全部数据,这个过程只需要回表一次

explain


关于 in 的顺序问题 解决方案

在这里插入图片描述


MVCC

https://www.bilibili.com/video/BV1864y1976i/?spm_id_from=333.337.search-card.all.click&vd_source=0722208728783f1453516ee9e0d6ca3f

Mvcc的实现主要是由隐藏的三个字段undolog, read view来实现的。

隐藏字段

在这里插入图片描述

undoLog

在这里插入图片描述

流程步骤:

  1. 事务1插入数据
    在这里插入图片描述
  2. 事务2更新name
    在这里插入图片描述
  3. 事务3更新age
    在这里插入图片描述

Read view

在这里插入图片描述
在这里插入图片描述
流程:
在这里插入图片描述
在这里插入图片描述
具体的比较规则:
在这里插入图片描述
在这里插入图片描述

总结
在这里插入图片描述


全表扫描

多次IO

在这里插入图片描述

索引

创建索引,相当于是给表中的字段创建了一个目录
在这里插入图片描述

索引文件

  • innodb:数据和索引存储在一个文件
  • MyIsam: 数据和索引分开存

索引的分类(5)

  • 主键索引
  • 普通索引
  • 唯一索引
  • 联合索引 (建议不要超过5个列)
  • 全文索引(MyIsam)

数据结构-树

在这里插入图片描述

在这里插入图片描述

  • 平衡二叉树(动态的二叉搜索树)

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

  • 红黑树
    在这里插入图片描述
    在这里插入图片描述

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

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


Update 锁

  • 如果一个字段上是有索引的,那么在一个事务下会开启行锁
  • 没有索引则开启表锁
  • 所以在update的时候,尽量走索引的列
  • 它是根据索引加的锁,锁的是索引。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值