MySQL 相关学习整理


MySQL 基础整理


前言

整理一下最近在学习的MySQL 相关的一些基础知识 以便未来复习


一、一条SQL的查询语句是如何执行的?

比如 你有一个简单的表 表里又一个ID字段 在执行

mysql>select * from T where ID = 1;

当执行这条sql语句 带返回查询结果 其中的过程是怎么的呢 ?

首先MySQL可以分为两部分 一部分是 Server层 一部分是 存储引擎层

server层 包括 包括连接器 缓存 解析器 优化器 执行器 等
存储引擎层 主要就是存储数据 提供读写接口 MySQL引擎主要有InnoDB,Memory,MyISAM等 不同的存储引擎的表数据存储方式都不同,支持的功能也不同。会按照功能进行选择,在没有指定选择引擎时,在MySQL5.5版本之后 默认使用InnoDB引擎。

1. 连接器

第一步是先连接到这个数据库,连接数据库的时候就用到了连接器。连接器就是负责跟客户端建立连接,获取权限,维持和管理连接的。

2.查询缓存

建立1连接之后 就可以正常的执行select语句了 MySQL拿到一个查询请求后,会先到查询1缓存中看一下是否是这个缓存,如果你的查询能在缓存中找到相应的key,则对应的value值会直接返回给客户端。
查询缓存不建议使用的原因是:
只要有对一个表的更新,这个表的所有查询缓存都会被清空。查询缓存的失效非常的频繁。在MySQL8.0版本之后 查询缓存的功能就被删除掉了。

3.分析器

分析器 主要是识别SQL语句 让MySQL知道你现在在做什么。

  1. 首先分析器会先做词法分析。识别你输入的字符串 分别是什么 代表1什么 以上面那个select查询为例:MySQL会从你输入的select关键字识别出来 这是一个查询语句,把字符串T识别出 表名 T 把字符串ID 识别成 列Id
  2. 语法分析:根据词法分析的结果 来通过语法分析器,判断输入的SQL是否满足MySQL的语法。如果你的语法不对,就会收到“You have an error in your SQL syntax”的错误提醒。

4.优化器

优化器主要处理两部分内容一个是决定使用哪个索引,一个是决定联表时各个表的连接顺序。

ps:具体如何选择索引 会后续进行补充。

5.执行器

执行器 简单的来说 就是要开始真正的执行SQL语句了

  1. 判断操作人是否对所查的表T有权限。如果没有返回ERROR 1142 (42000): SELECT command denied to user ‘b’@‘localhost’ for table 'T’的错误提示。
  2. 如果有权限。会根据表的引擎定义 调用相应引擎的接口。

二、一条SQL的更新语句是如何执行的?

上面说了一个查询语句的执行过程 一个更新语句和查询语句的过程大体类似 只是加入了 binlog 如果是InnoDB 还会加入redo log的操作 具体如下:

mysql> create table T(ID int primary key, c int);

mysql> update T set c=c+1 where ID=2;

1.更新操作也会完成Server层里 连接器 缓存 分析器 优化器 执行器这些部分

2.执行器阶段 会追加一个日志的模块

MySQL自带的日志模块是binlog 所有存储引擎都可以进行使用,常用的InnoDB引擎还有一个redo log日志模块。

  1. 拿到需要查询的数据 之后把c的值改为c+1
  2. 调用引擎API接口 写入这一行数据
  3. InnoDB会把数据保存在内存中,同时记录redo log 此时的redo log进入prepare状态。之后通知执行器,已经执行完 可以进行提交。
  4. 执行器收到通知后 会记录binlog 然后调用1引擎api接口 提交redo log为提交状态。
  5. 完成更新操作。

具体日志的处理过程可参考
redolog binlog 详解

为什么InnoDB需要用两个日志模块。主要是因为InnoDB需要用redo log来支持事务的操作

redo log的prepare状态和提交状态 主要是实现 redo log和binlog的数据的一致性

三、MySQL索引

索引是MySQL中很重要的部分 索引可以提高数据查询的效率 就像书的目录也一样 索引的数据结构 有hash 二叉树 N叉树 B+树 现在最常用的InnoDB引擎用的就是B+树做的底层数据结构。在InooDB中表都是根据主键顺序以索引的形式存放的,这种存储方式的表叫做索引组织表。
所有数据都是存在InnoDB上的 每一个索引在InnoDB里面都对应一颗B+树

下面主要介绍几种常用的索引类型。

1.主键索引(聚簇索引)和非主键索引(二级索引)

主键索引的叶子结点 存储的是整行数据。非主键索引的叶子结点内容是主键的值。
主键索引和非主键索引查询过程的区别:

mysql> create table T(
id int primary key, 
k int not null, 
name varchar(16),
index (k))engine=InnoDB;

select* from T where ID=500,这是用主键索引进行的查询,只需要搜索ID这可B+树。
select* from T where K=1,这里用的就是非主键索引,需要先搜索K的B+索引树 得到ID的值,之后再到ID的B+索引树中在搜索一遍。这个过程就称为回表
也就是说 非主键索引的查询 会多扫描一颗索引树。

2.联合索引

联合索引,就如同其名。就是多个索引 共同建立索引,但是建立联合索引的时候要考虑索引的先后顺序,因为索引又一个最左前缀原则,下面会针对最左前缀原则 进行详细讲解。

3.覆盖索引

覆盖索引,顾名思义就是把主键索引覆盖进查询条件。覆盖索引的目的其实就是尽量减少一次回表的操作,减少多查询一棵树带来的额外开销。
举个例子:
select ID from T where k betwwen 3 and 5;这个查询因为只需要查ID的值,而Id的值就已经在B+索引树的叶子结点上了。所以就不需要回表操作。

覆盖索引一般都配合联合索引共同使用。例如:
当我们查询用户信息,可以直接在身份证号上添加索引,就可以满足相应的查询。那么还有必要做身份证号和姓名的联合索引吗。如果有一个高频请求,需要通过身份证号查询对应的姓名,这时候这个联合索引就有意义了,他可以在这个高频请求上用到覆盖索引,避免了回表的操作,减少语句的执行时间。

4.最左前缀原则

5.索引下推

6.InnoDB中索引的数据结构

  1. 为什么选择B+树做存储索引的数据结构

7.什么时候索引会无效

因为sql执行的时候 优化器 会选择最优的索引或者选择不使用索引 所以有些情况会导致索引无效。还有一些特殊原因可能会导致索引无效化。下面列举了索引无效的情况:

  1. 当用or时 or会使索引失效 除非or两边用的是一个索引条件 例:
    索引a,b
    select* from a=1 or a=2; 索引有效
    select* from a=1 or b=2; 索引失效
  2. 使用联合索引(a,b) select * from T where b=1 and a=1 这时候a的索引是有效的 b的索引是无效的
  3. 模糊查询 like 以%开头
  4. 优化器内 分析 用索引 可能没有全表查询快的时候 也会选择不用索引
  5. 如果列类型是字符串 要使用引号 不然索引失效
  6. where语句中 有<> != 时不会使用索引
  7. where语句中 使用not in 不会使用索引
  8. 应尽量避免对字段进行null值判断 容易导致引擎 会放弃索引 使用全表扫描
    参考:索引失效

8.为什么要用自增Id做主键索引

相信大家总会在各种资料中看见,建议使用自增Id来做主键索引,为什么要用自增id做主键索引呢,比如用户表 用手机号 或者生份证号做索引不可以吗

  1. B+树为了维护索引的有序性,在插入新值的时候会做必要的维护。如果插入的数值不是现存记录中最大的,就会导致比这个数值大的数据进行挪动。举个例子:假如上面建的的表中ID有300 600 700三个数据。当你插入200这个数据的时候 300 600 700 这三个数据的位置都需要往后挪动一位。
  2. 如果你插入的这个数据所在位置的数据页已经满了,根据B+树的算法 这时候你需要申请一个新的数据页,然后挪动部分数据过去。这个过程就称为也分裂。影响性能。除了性能外,页分裂操作还会影响数据页的利用率。原本放在一个页的数据,现在分到两个页中,整体利用率降低大约百分之50.
  3. 当相邻的两个页 由于删除数据导致利用率很低之后,会可能对数据页做合并操作,合并过程就基本是页分裂的逆过程。

自增主键 就可以避免上面的问题的发生。每次插入操作都是追加操作,都不涉及挪动其他记录,也就不会触发叶子结点的分裂。
从存储空间上来看 因为每个非主键索引的叶子结点都有主键的值。如果身份证号做主键,每个二级索引的叶子节点占用用20个字节。而如果整型做主键只需要4个字节,长整型也只需要8个字节。 显而易见,主键长度越小,二级索引的叶子结点就越小,二级索引占用的空间就越小。

当然也有场景可以用身份证号来做索引 如下例子:
业务需要 只有一个索引,该索引必须是唯一索引。
因为没有其他索引 所以也就不用考虑 叶子节点大小的问题。尽量使用主键查询,直接把这个索引设置为主键,可以避免查询回表导致搜索两颗树。

四、MySQL的锁

锁是MySQL中很重要的部分

1.全局锁

2.表锁

3.行锁

五、MySQL的事务

事务

1.事务隔离

事务隔离级别有:
读未提交
读提交
可重复读
串行化

2.事务到底是隔离还是不隔离


总结

MySQL 语句的执行过程

查询:连接器->缓存->分析器->优化器->执行器->引擎
更新:连接器->缓存->分析器->优化器->执行器->引擎->redo log ->prepare->binlog->commit

ps: 本文还在持续更新中…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值