阿里的几个 MySQL 面试题,反正我是跪了!

SQL herman 79浏览
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xmtxtt,发送下载链接帮助你免费下载!
本博客日IP超过1800,PV 2600 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog,之前的微信号好友位已满,备注:返现
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序

测试是来表明 bug 的存在而不是不存在!同样的,面试是证明你有经验而不是你没有经验!

昨天,微信群里有人在总结学习过程,如果让学习更高效。有人说做笔记,有人说画思维脑图。。。而我则喜欢刷面试题。于是在群里有人提问 MySQL 的情况下,我找了几道具说是阿里的 MySQL 面试题,大家可以借助高考 + 端午的空闲时间来检验一下自己!

数据库优化漏斗法则

在开始之前,我先来解释两个概念。快照读 (snapshot read)与当前读 (current read)。快照读,读取的是记录的可见版本 (有可能是历史版本),不用加锁。当前读,读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。OK,下面来看几个问题!(以下问题都是基于 innoDB 存储引擎)

1、简单的 select 查询,如:select * from xttblog where id = 1; 是属于快照读吗?

简单的 select 操作,属于快照读,不加锁。

2、属于当前读的常见 SQL 语句有哪些?

select * from xttblog where ? lock in share mode;
select * from xttblog where ? for update;
insert into xttblog values (…);
update xttblog set ? where ?;
delete from xttblog where ?;

常见的上面 5 种 SQL 都是属于当前读,读取记录的最新版本。并且,读取之后,还需要保证其他并发事务不能修改当前记录,对读取记录加锁。其中,除了第一条语句,对读取记录加 S 锁 (共享锁)外,其他的操作,都加的是 X 锁 (排它锁)。

3、如果 id 是主键,且是 RC 隔离级别,SQL:delete from xttblog where id = 10 会加锁吗?

会加 X 锁,排它锁。只需要将主键上,id = 10 的记录加上 X 锁即可。

4、问题 3 种的 id 主键改为唯一索引后,SQL:delete from xttblog where id = 10 会加锁吗?

若 id 列是 unique 列,其上有 unique 索引。那么 SQL 需要加两个 X 锁,一个对应于 id unique 索引上的 id = 10 的记录,另一把锁对应于聚簇索引上的相对于 id unique 对应的记录。

5、主键索引和唯一索引的区别?

主要区别总结如下:主键是一种约束,唯一索引是一种索引,两者在本质上是不同的。主键创建后一定包含一个唯一性索引,唯一性索引并不一定就是主键。唯一性索引列允许空值,而主键列不允许为空值。主键列在创建时,已经默认为空值 + 唯一索引了。主键可以被其他表引用为外键,而唯一索引不能。一个表最多只能创建一个主键,但可以创建多个唯一索引。主键更适合那些不容易更改的唯一标识,如自动递增列、身份证号等。在 RBO 模式下,主键的执行计划优先级要高于唯一索引。 两者可以提高查询的速度。

6、唯一性太差的字段不宜建立索引的原因是什么?

因为mysql首先会将索引中的键值取出来与内存中存储表数据的页中的数据相比较,但是数据页中的数据的顺序和索引队列中键值的顺序并不是一致的。假如索引中的键值 a 先在数据页x中找到了符合的数据,然后又在数据页 y 中找到了符合条件的数据,这时 mysql 便会把数据页 x 销毁掉,把数据页 Y 读到内存中。如果这时候还有键值 b,然后键值 b 找的数据又在数据页 x 上,则 mysql 又要把数据页 x 读到内存中。也就是说从索引去寻找对应的表数据的时候是随机访问的。(实际情况应该是内存中缓存了好几页的数据,应该不只一页,但是这里假定线程内存中只存在一张页表)。这样的随机访问所造成的 io 消耗是比全表扫描的 io 消耗来得大的,还不如遍历整张表。

举个极端的例子。表 xttblog(ID,col1,col2,col3,col4,..col100) 共 100 个字段,现在 COL4 上创建索引,而 COL4 中所有的值都为 1,update a set col4 = 1,10000 条记录,COL4 都是 1。如果你查询 select * from xttblog where col4 = 1; MYSQL 就不会再去走索引。 因为如果走索引反而速度慢。 MYSQL 会自行判断是否需要使用索引。这也是为什么经常会看到 EXPLAIN 中明明有索引,但并未被使用。同样,即使 update xttblog set col4 = 0 where id = 10,这样, 仅 ID = 10的记录 COL4 = 0,而其余 9999 条记录仍是 COL4 = 1。 同样 select * from A where col4=1; 如果此时去走索引开销同样 比不走索引要大。

综上,唯一性太差的字段不宜建立索引。

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加QQ1群:135430763(2000人群已满),QQ2群:454796847(已满),QQ3群:187424846(已满)。QQ群进群密码:xttblog,想加微信群的朋友,之前的微信号好友已满,请加博主新的微信号:xttblog,备注:“xttblog”,添加博主微信拉你进群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作可添加助理微信进行沟通!

本文原文出处:业余草: » 阿里的几个 MySQL 面试题,反正我是跪了!