26丨索引的使用原则:如何通过索引让SQL查询效率最大化?
思考并回答以下问题:
- 实际上多个单列索引在多条件查询时只会生效一个索引(MySQL会选择其中一个限制最严格的作为索引),所以在多条件联合查询的时候最好创建联合索引。
- 在进行SELECT查询的时候,先进行GROUP BY,再对数据进行ORDER BY的操作。怎么建立联合索引?
面向对象设计原则
思考并回答以下问题:
- 开闭原则是目标,里氏代换原则是基础,依赖倒转原则是手段。怎么理解?
- 为什么在对每一个模式进行优缺点评价时都会将开闭原则作为一个重要的评价依据?
- 为什么在程序中尽量使用基类类型对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象?
- 为什么用接口和抽象类进行变量类型声明、参数类型声明、方法返回类型声明,以及数据类型的转换等,而不要用具体类来做这些事情?
- 为什么在程序中应该尽量使用抽象层进行编程而将具体类写在配置文件中?
- 为什么接口应该尽量细化,同时接口中的方法应该尽量少?
- 通过继承来进行复用的主要问题在于继承复用会破坏系统的封装性,因为继承会将基类的实现细节暴露给子类。这种复用名词是什么?
- 什么是“黑箱”复用?
30 | 如何使用Redis实现分布式锁?
思考并回答以下问题:
- 为什么想要实现分布式锁,必须要求Redis有「互斥」的能力?
- 使用setnx和del实现分布式锁存在的两个问题是可能会忘了执行del命令,或者b把a的锁删除了,要怎么处理呢?
SET lock_key $unique_id EX $expire_time NX
就可以实现最简单的分布式锁,怎么理解?还有怎么优化?
20 | 幻读是什么,幻读有什么问题?
思考并回答以下问题:
select * from t where d=5 for update;
是怎么加锁的,加的锁又是什么时候释放的呢?- 幻读指的是一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行。幻读仅专指“新插入的行”。怎么理解?
- 在可重复读隔离级别下,普通的查询是快照读,是不会看到别的事务插入的数据的。因此,幻读在“当前读”下才会出现。什么是快照读?什么是当前读?
- 当前读的规则,就是要能读到所有已经提交的记录的最新值。怎么理解?
- 产生幻读的原因是,行锁只能锁住行,但是新插入记录这个动作,要更新的是记录之间的“间隙”。因此,为了解决幻读问题,InnoDB只好引入新的锁,也就是间隙锁(Gap Lock),锁的就是两个值之间的空隙。间隙锁是在可重复读隔离级别下才会生效的。怎么理解?
- 跟间隙锁存在冲突关系的,是“往这个间隙中插入一个记录”这个操作。间隙锁之间都不存在冲突关系。怎么理解?
- 间隙锁和行锁合称next-key lock(临键锁),每个next-key lock是前开后闭区间。怎么理解?
- 如果把隔离级别设置为读提交的话,就没有间隙锁了。怎么理解?
- 读提交隔离级别加binlog_format=row的组合。怎么理解?
18 | 为什么这些SQL语句逻辑相同,性能却差异巨大?
思考并回答以下问题:
- 对索引字段做函数操作,可能会破坏索引值的有序性,因此优化器就决定放弃走树搜索功能。怎么理解?
- 每次你的业务代码升级时,把可能出现的、新的SQL语句explain一下,是一个很好的习惯。为什么?
10 | MySQL为什么有时候会选错索引?
思考并回答以下问题:
- 选择索引是优化器的工作。在数据库里面,扫描行数是影响执行代价的因素之一。扫描的行数越少,意味着访问磁盘数据的次数越少,消耗的CPU资源越少。优化器还会结合是否使用临时表、是否排序等因素进行综合判断。怎么理解?
show index from t;
能看到一个索引的基数。有什么作用?analyze table t
命令,可以用来重新统计索引信息。怎么理解?- 优化器会计算在主键索引直接扫描和使用普通索引回表的代价,从而做出选择。怎么理解?
07 | 行锁功过:怎么减少行锁对性能的影响?
思考并回答以下问题:
- MySQL的行锁是在引擎层由各个引擎自己实现的。怎么理解?
- 如何通过减少锁冲突来提升业务并发度?
- 在InnoDB事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。怎么理解?
- 事务A和事务B在互相等待对方的资源释放,就是进入了死锁状态。怎么理解?
- 一种策略是,直接进入等待,直到超时。这个超时时间可以通过参数innodb_lock_wait_timeout来设置。这种策略好吗?
- 对于相同行的更新,在进入引擎之前排队。这样在InnoDB内部就不会有大量的死锁检测工作了。怎么理解?
- 如果你的事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁的申请时机尽量往后放。怎么理解?
- 减少死锁的主要方向,就是控制访问相同资源的并发事务量。使用分治思想。怎么理解?
工作面试老大难-锁
思考并回答以下问题:
- 当事务T1改动了这条记录后,就生成了一个锁结构与该记录关联,因为之前没有别的事务为这条记录加锁,所以is_waiting属性就是false,我们把这个场景就称之为获取锁成功,或者加锁成功。怎么理解?
- 意向共享锁,英文名:Intention Shared Lock,简称IS锁。当事务准备在某条记录上加S锁时,需要先在表级别加一个IS锁。怎么理解?
- 意向独占锁,英文名:Intention Exclusive Lock,简称IX锁。当事务准备在某条记录上加X锁时,需要先在表级别加一个IX锁。怎么理解?
- IS、IX锁是表级锁,它们的提出仅仅为了在之后加表级别的S锁和X锁时可以快速判断表中的记录是否被上锁,以避免用遍历的方式来查看表中有没有上锁的记录,也就是说其实IS锁和IX锁是兼容的,IX锁和IX锁是兼容的。怎么理解?
事务隔离级别和MVCC
思考并回答以下问题:
- MySQL是一个客户端/服务器架构的软件,对于同一个服务器来说,可以有若干个客户端与之连接。怎么理解?
- 明明把数据更新了,最后也提交事务了,怎么到最后说自己啥也没干呢。这是脏写。怎么理解?
- read uncommitted有脏读问题,read committed有不可重复读问题,repeatable read有幻读问题,serializable上面问题全部解决。怎么理解?
- 脏写 > 脏读 > 不可重复读 > 幻读。怎么理解?
- MVCC是通过三个隐藏字段,undo log版本链和read view可见性算法实现的。怎么理解?