mysql 判断临时表存在_常见的MySQL面试点(二)

f04e967fd026aec219cc1f06f605a01e.png

1. 什么是死锁?如何解决数据库死锁?

因为数据库锁的最细粒度是行锁,当一个开启事务后,修改某行,在提交事务前,同一行数据在另一个线程也出现了修改。这个时候,后面出现的这个修改语句会发生堵塞,等待前面的事务提交后再开始执行。

如果同一时刻两个线程发生这种情况:

begin;update A 行;update B 行, commit;

begin;update B 行;updateA 行, commit;

两个线程互相等待另一方提交事务,这个时候就出锁冲突,出现死锁。

解决死锁:

• 把最容易出现死锁的行放到整个事务的最后执行,减少死锁时间,提高并发。

• 数据库配置中有两种策越来解决死锁:

• 死锁超时等待,当发生死锁的时候,第一个死锁线程等待50s后自动释放锁,其他线程才继续执行,这个一般不采纳。

• 死锁检测,每当开启一个事务的时候,检测自己修改的行,是否被别的线程锁住,判断自己是否发生了死锁;缺点是:CPU负担加重。

2. 事务之间是如何隔离的?

每个事务开启的时候会创建一个read-view视图,即使其他事务修改了数据,但是不影响本事务的视图,另外视图的创建就是给事务添加一个版本号,并非直接copy一份数据。因此同一行数据可能存在版本号,存在多个视图,通过视图进行事务隔离。

3. 普通索引和唯一索引的区别?该如何选择?

使用普通索引查询时,查询索引树上的叶子节点,命中目标后,还会继续往下查找;使用唯一索引查询时,命中目标后直接返回。

查询时,性能上两者微乎其微,因为查询时是按数据页查询的,每次返回数据是把目标行的数据页都返回过来,普通索引的多做的一次判断操作只是一个指针的挪动。

数据更新时,每次都是将数据更新到change buffer内存中,以后查询时只要查询内存中的数据,目标是减少磁盘访问。change buffer也支持持久化,当更新后访问这个数据页时会触发持久到磁盘中,同时后台也会定期持久化。当查询时假如changebuffer中不存在数据,则将数据从磁盘中读取到change buffer中。

当数据存在内存中时:

• 普通索引直接将更新写入change buffer。

• 唯一索引先判断数据的唯一性,再写入。

当数据只存在磁盘中时:

• 普通索引直接将更新写入change buffer。

• 唯一索引先将数据写入内存中,再判断,最后更新。

因此:多利用change buffer 可以提高系统性能,特别是写多读少的情况,写到内存后,只要不立刻出现查询,都可以交给后台线程持久化到磁盘。 例如账单,日志系统,因此这种情况推荐使用普通索引。反之,写少读多的场景,使用唯一索引。

4. 为什么sql语句突然慢了一下?

sql更新时,首先会把更新写到内存redo log中,然后返回客户端更新成功,当redo log 写满了的时候,再flush 内存中的redolog到磁盘中。这个过程可能导致sql语句抖动一下。

5. 为什么表数据删除了一半?但是文件大小不变?

mysql的数据默认是存放到.ibd 为后缀的文件当中的,当使用delete 删除数据时,mysql其实就是把对应的B+树节点标志为已删除可复用的状态。这个时候如果想减少这种空洞,应当使用 alter table A engine=InnoDB 命令来重建表,这种重建是一种online DDL在线重建。

这个过程是:首先创建一个和原表一样结构的临时表,把所有数据按照顺序写到临时表中,因为临时表是新建的表,所以不存在空洞的问题。数据导入完毕后再将临时表替换为原表。online DDL在线重建就是当导入数据的过程中,原表又插入了新的数据,新数据是保存在一个临时文件中,等前面导入完成后,再导入这个临时文件的新数据。确保导数据的过程中不丢失数据。

6. count(*)和count(字段)的区别?

count(*)因为肯定不是null, 只需要按行累加和count(1)差不多。

count(字段)需要判断字段不能为null,不为null才进行累加。

7. order by 的执行流程?

使用explain 可以看到extra中 有Using fileSort用于排序。首先初始化一个sort buffer内存用于排序,通过主键查找到所需要的数据后存放到sort buffer当中,再按照特定字段进行排序,最后返回结果集。排序是一个成本较高的操作,但是如果是按照索引排序,这个时候就不需要初始化sort buufer排序了,因为查到到的数据已经默认排序好了,直接返回结果集。

8.查询遇到哪些坑?

• 在where条件后使用函数,无法走索引。例如 where month(filed) = 12,使用 explain 命令可以看到执行计划上 rows走的是全局遍历。

• 索引字段上,类型转换后无法走索引。例如字段a是varchar类型,但是 where a = 142。这样也无法走索引。

• 小表 left join大表 。 在关联查询时, 小表驱动大表,可以提高查询效率。

• in和exist的区别;使用in 的时候,先查询主表的数据,再判断主表中符合的条件。 使用exist的时候,先查询条件表再放到主表中判断是true false,true则返回。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值