MySQL

索引

什么是索引

索引是一种数据结构, 为了快速定位到数据而存在

为什么使用索引

1 索引可以减少IO次数
2 索引可以把随机IO转换为顺序IO
3 在分组和排序的时候避免使用临时表

使用什么算法

1 B+树算法

为什么不使用二叉查找树

首先说一下二叉查找树的规则
1 左节点要小于根节点
2 右节点要大于根节点
在这里插入图片描述
缺点
二叉查找树可能会把树的结构转换为一个线性链表的结构

在这里插入图片描述

为什么不使用平衡二叉树

规则
首先平衡二叉树也是满足左小于根,右大于根的规则
但是它的左右节点的高度差不能超过1

平衡二叉树解决了二叉查找树 线性链表的问题

平衡二叉树存储了什么数据

1 关键字
2 数据区
3 子节点引用

缺点
数据存在的层数,决定了我们要进行多少次IO操作
并每个磁盘块保存的数据量太小, 没有充分利用好操作系统的磁盘存储
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

为什么不使用B-树(多路平衡查找树)(balance)

规则
1 处根节点和叶子节点以外,其他的每个节点必须有m/2个孩子节点
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2 所有叶子节点必须在同一层
在这里插入图片描述
3 符合平衡二叉树的观点, 左右节点高度差不会超过1

4 B树里面所有的节点都存储了数据, 这样的导致查询数据的时候,导致性能会减低

5 使用的是索引顺序IO,根据二分法查找数据

缺点: 在B树的节点上存储了数据, 减少了保存其他键值的空间,数的高度决定了我们要进行多少次IO操作.

为什么使用B+树

B-树解决了磁盘IO性能,但是并没有解决元素遍历效率低问题, 而B+树只需要遍历叶子节点就可以遍历整颗树

规则
1 左小右大
2 非叶子节点之存储数据索引,所有数据必须要找找到叶子节点才能获取,所以每次数据查询次数都是一样的
3 保存了父节点的所有键值和键值对应的数据,每个叶子节点的键值从小到大连接

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

MyISAM B+索引实现

1 叶子节点存储了索引的值(myisam的主键和辅助主键没有区别,所以他没有主外键)
在这里插入图片描述

Innodb B+索引实现

myisam叶子节点存储的数据地址, innodb叶子节点存储的是数据,索引的key就是索引主键,
在这里插入图片描述
什么叫做聚集索引
聚集索引的意思就是叶子节点存储的是data,则表示这种索引就是聚集索引,

聚集索引,非聚集索引,覆盖索引

聚集索引
给表建立一个主键, 表在磁盘上的整齐排列的顺序转换为树状结构, 整个表转换为了一个索引, 当整个表变成一个索引的时候那么他就是聚集索引

键值的逻辑顺序决定了表中对应行的物理顺序(内容本身就是按照一定的规则排列的目标成为聚集索引)

非聚集索引
表示非主键字段创建索引,如果跟表里的多个字段创建索引,那么会出现多个独立的索引结构,每个非聚集索引互相之间不存在关联
该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同, 他的叶子节点存储的是指针,而不是数据data

聚集索引和非聚集索引的区别: 聚集索引是有序排列,叶子节点存储的是data, 非聚集索引是无序的存储数据,也就是叶子节点存储的是指针(可以用innodb和myisam中B+树的存储结构做对比)

覆盖索引
表示没有走的叶子节点就已经找到data

Mysql 查询执行的路径

客户端和服务端建立连接

  使用的是半双工模式
  当出现故障问题的时候使用show processlist进行查看链接状态

查询缓存

查询优化器

解析器:把SQL解析成树, 预处理:是否正确

执行引擎

mysiam innodb

返回给客户端

优化

explain 解释器包含内容

select_type: select简单的查询, primary 包含子查询

type: system, const, eq_ref . ref.range, index , all

possible_keys: 查询过程中可能用到的索引

key:用到的索引

rows:扫描的行数

索引失效原因 为什么?

没有左查询

在B+数中我们是按照左必右开的思想去查询的,也就是从做边开始查询,所以在底层的查询的时候首先根据第一个索引去找,但是如果你如果没有使用第一个索引,那么这个时候他就找不到了,所以全表扫描了

使用%立刻

如果使用模糊查询,不明确,所以也会全表扫描

使用or

字符串没有""号

mysql还需要帮你加"",她会认为不使用索引可能会更快

使用 is null

mysql中不存储null值,所以全表扫描

如何定位慢SQL

1 通过项目中的durid查看
2 打开mysql的慢日志查看: set global show_query_log=on
3 使用explain解析SQL为什么慢

事物

事物特性

A
原子性: 不可分割
C
一致性:事物操作的数据以及状态改变是一致的
I
隔离性:一个事物在操作数据提交之前,对其他事物是可见的.
D
持久化:存储到磁盘上

隔离级别如何实现

通过MVCC和锁实现的

什么是MVCC

Multiversion concurrent control 多版本并发控制

每张表中存储了2个字段, 数据行版本号,删除版本号

有的时候我们会发现当我们更新数据之后,假如没有commit,为什么还能查询以前的数据呢 ,就是因为mvcc的多版本控制,让我们可以查询上一个版本的内容

MVCC插入逻辑流程

当我们进行操作的时候,首先会拿到事物的id, 然后插入数据到表中,把事物id插入到数据行版本号中
在这里插入图片描述

MVCC删除逻辑流程

拿去当前事物id,放入到删除版本号里面
在这里插入图片描述

MVCC更新

1 copy一行数据
2 在把当前到的事物id更新到数据行版本号上, 然后把上一个的删除版本号更改当前的事物id

MVCC查询逻辑流程

1 查询拿着事物id,当前事物id小于查询数据行的版本号
2 再拿着事物id查询,事物id大于删除版本号,或者删除版本号为null的
在这里插入图片描述

undo log 什么

可以把数据返回到某一个状态,因为在数据操作之前会备份数据到undo log中

为什么 会有undo log

undo

undo log 有什么功能

解决了mysql并发问题, 保证数据的一致性

MVCC与Undo Log关系

mvcc的方法是基于undo log

当前读和快照读

当前读表示增删改
快照读表示普通select,从缓存中读取

Redo log

减少每次事物的提交都需要进行IO操作, 所以让事物提交的时候首先把数据方道平Redo log的缓冲区里面,然后再更新磁盘

Mysql锁

什么是锁

互相霸占着彼此的资源不放手

表锁和行锁的区别

行锁表示在where条件我们使用了索引,则产生的行锁
如果Where条件没有索引,那么他会全表扫描,所以会出现表锁

mysql锁类型

共享锁

S锁: 加S锁,可以读取数据当时不可以更新数据,读锁,可以加读锁

排它锁

X锁:加X锁, 排它锁,表示什么锁都不可以加, 只允许他一个事物读和写

意向锁共享IS

在加S锁的时候,判断是否有意向锁共享,如果有则不加

意向锁排他锁IX

在加X锁的时候,判断是否有意向排它锁,如果有则不加

临键锁(Next key)innodb默认行锁算法

假如使用的是排它锁,并且还使用where条件的进行范围查询,并且where条件后面使用了索引, 他会锁住当前空间和下一个空间,也就是左开右必

为什么Innodb默认选择临键锁

innodb默认采用的不可重复读, 并且解决了幻读的问题, 当B+树命中这块空间的时候,则不能再次进行插入,所以解决了幻读问题.

什么间隙锁

只锁住范围之内的数据

什么是记录锁

主键索引,锁住一行数据,一般用的type为eq_ref

锁解决并发问题

X锁解决脏读问题
S锁解决了重复读问题
临键锁解决了幻读问题,主要是记录锁和间隙的结合体

死锁避免

1 同一个事物尽可能做到一次锁定所有资源,减少死锁概率
2 添加合理的索引,这样可以快速
3 减少锁的占用时间

三范式

1 原子性,属性不可以再分割
2 一张表里只有一个主键
3 一个表里面不可以存储其他表中的字段

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章