MYSQL 知识问答

mysql基础问题

mysql 事务隔离级别

 - 读未提交
 - 读已提交
 - 可重复度
 - 串行化(每个读操作都加锁)

为什么要用可重复读

废话,我如果在一个事务中,两次查询的结果不一致,那我到底以哪个结果作为基准来执行我的程序

mysql知识进阶

什么是当前读

当前读,顾名思义 读当前最新的数据
比如说我们平时用到的 【update,delete,insert,for update,lock in share mode】都是当前读
读取的时候还会对当前的数据进行加锁,防止别的事务对当前数据进行修改。
(其实不光会对当前数据进行加锁处理,有时候还会将某个间隙进行加锁,也就是间隙锁,下面再讲)

什么是 快照读

快照,快照,这个名字多熟悉,故名思义,就是对某个时刻的某些数据的缓存。
mysql 中不加锁的select就是快照读 比如 select * from tab where name = '小二'
mysql中 快照读代表着 事务只能看到当前事务可以看到的数据,并不一定能看到最新的数据。
mysql 的快照读实现了 读已提交和可重复度两种模式

为什么要用快照读

因为他快啊 。
想比较与加锁的操作,快照读是 不加锁的非阻塞读,能够有效的提高并发性能。
不加锁====降低开销

快照读是怎么实现的

mysql实现了mvcc(多版本并发控制),在查询的时候会生成一个readview,
readview中包含当前活跃的事物和一些其他数据,mysql 会通过对比来查询出当前事务可以看到的数据。
简单来说是通过乐观锁的方式来实现的,因为 除了悲观锁 剩下的都是乐观锁实现
一句话概括就是这么简单
具体如何实现,下面再讲

mvcc的实现原理

MVCC原理
这个文章写的太好了,就没必要写了。

可重复度和读已提交在mvcc中的区别是什么

其实mvcc的实现原理已经看明白的话 这个问题很简单
两者的区别其实就是 readview的生成规则不一样
想想一下如果 readview是每一次查询的时候都生成一次,那不就是读已提交

间隙锁是干嘛的

想象这么一个场景:
#表结构:
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `age` int(2) DEFAULT NULL,
  `sex` int(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `age` (`b`)
) ENGINE=InnoDB;
#数据
INSERT INTO `user` (`id`, `age`, `sex`) VALUES ('1', '18', '0');
INSERT INTO `user` (`id`, `age`, `sex`) VALUES ('1', '20', '0');
INSERT INTO `user` (`id`, `age`, `sex`) VALUES ('1', '22', '0');
INSERT INTO `user` (`id`, `age`, `sex`) VALUES ('1', '30', '0');
INSERT INTO `user` (`id`, `age`, `sex`) VALUES ('1', '31', '0');
INSERT INTO `user` (`id`, `age`, `sex`) VALUES ('1', '32', '0');

#索引树
在这里插入图片描述

在一个事务中(可重复读场景下)有以下两个sql
select * from user where age = 22 for update;(name有索引)
中间隔了5s
select * from user where age = 22 for update;(name有索引)
中所周知,mysql会锁定age = 22的数据
在只有行级锁的情况下能保证我第二次查询的时候也只有1条数据吗
答案是不能!!!
因为 我可能将其他数据的age修改为22
这样不就违背了 可重复读的初衷了
间隙锁就是来解决这个事情的
间隙锁会锁住name的索引树 小二的两侧的间隙(见下图)
这样别的update/insert/delete操作就无法进行,
这样就保证了 可重复读

在这里插入图片描述

mysql 优化

前述:mysql的优化建立在对索引结构B+树了解的前提下
自己找资料吧

什么是回表

	了解回表就必须了解
	聚集索引(主键索引)B+树叶子结点储存的是 行数据
	非聚集索引(普通索引)B+树叶子结点存储的是 主键id
	比如说 select b from tab where a = '123';(b 有索引)
	那么这个查询就会设计到回表
	
	查询过程:
	第一步:
		去b的索引树查找符合a=‘123’的数据,最终查找到,但是查到的是一个主键id
	第二步:
		拿着主键id去主键索引树 查询该id的数据
	这就是回表,总共进行了两次索引树的查询

回表怎么处理

	回表的解决办法就是 建立组合索引 
	建立 a和b的组合索引
	这样在查询的时候在第一次搜索索引树的过程中也有b的信息,自然就不需要第二次查询了

范围查询必然会不走索引吗(between and,in 。。。)

	不一定
	如果范围较小 会走索引
	范围较大,mysql分析器 分析出来该sql走索引的代价比全表代价还大,就直接不走索引了。

说说对最左前缀原则的理解

通过索引树就比较好理解了 组合索引 a和b和c的话在索引树中是这样的结构
在这里插入图片描述

在是先通过a来排序的,如果你先用b是无法来进行操作的。

什么是索引下推

索引下推index condition pushdown(ICP)
比如说一个sql 
SELECT * from tab where  a like '123%' and b=1
a和b是组合索引

根据最左匹配原则 遇到非等值判断时匹配会停止
那所以:
就只有 a可以用上索引
这样的索引查询步骤是:
第一步:
	现在索引树查找到 like 123%的所有的数据的 主键id
第二部:
	拿着主键id 去主键索引树查询相应数据
最后对比age
到此结束
but····························
上面的那个匹配原则其实都是5.5或者5.5之前版本的问题
5.6之后的版本没有这样的问题,就是通过索引下推解决的
有了索引下推之后就只查询一次索引树:
第一步:
	现在索引树查找到 like 123%的数据 并对比 age的值
到此结束
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值