一、数据库架构
1、说说MySQL的基础架构图给面试官讲一下MySQL的逻辑架构,有白板可以把下面的图画一下,图片来源于网络。
MySQL逻辑架构图主要分三层:
第一层负责连接处理,授权认证,安全等等
第二层负责编译并优化SQL
第三层是存储引擎。
2、一条SQL查询语句在MySQL中如何执行的?先检查该语句是否有权限,如果没有权限,直接返回错误信息,如果有权限会先查询缓存(MySQL8.0版本以前)。
如果没有缓存,分析器进行词法分析,提取SQL语句中select等关键元素,然后判断SQL语句是否有语法错误,比如关键词是否正确等等。
最后优化器确定执行方案进行权限校验,如果没有权限就直接返回错误信息,如果有权限就会调用数据库引擎接口,返回执行结果。
二、SQL优化
1、日常工作中你是怎么优化SQL的?可以从这几个维度回答这个问题:
1)优化表结构
①尽量使用数字型字段
若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
②尽可能的使用varchar代替char
变长字段存储空间小,可以节省存储空间。
③当索引列大量重复数据时,可以把索引删除掉
比如有一列是性别,几乎只有男、女、未知,这样的索引是无效的。
2)优化查询
应尽量避免在where子句中使用!=或操作符
应尽量避免在where子句中使用or来连接条件
任何查询也不要出现select*
避免在where子句中对字段进行null值判断
3)索引优化
对作为查询条件和orderby的字段建立索引
避免建立过多的索引,多使用组合索引
2、怎么看执行计划(explain),如何理解其中各个字段的含义?在select语句之前增加explain关键字,会返回执行计划的信息。
id列:是select语句的序号,MySQL将select查询分为简单查询和复杂查询。
select_type列:表示对应行是是简单还是复杂的查询。
table列:表示explain的一行正在访问哪个表。
type列:最重要的列之一。表示关联类型或访问类型,即MySQL决定如何查找表中的行。从最优到最差分别为:systemconsteq_refreffulltextref_or_nullindex_mergeunique_subqueryindex_subqueryrangeindexALL
possible_keys列:显示查询可能使用哪些索引来查找。
key列:这一列显示MySQL实际采用哪个索引来优化对该表的访问。
key_len列:显示了MySQL在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列。
ref列:这一列显示了在key列记录的索引中,表查找值所用到的列或常量,常见的有:const(常量),func,NULL,字段名。
rows列:这一列是MySQL估计要读取并检测的行数,注意这个不是结果集里的行数。
Extra列:显示额外信息。比如有Usingindex、Usingwhere、Usingtemporary等。
3、关心过业务系统里面的SQL耗时吗?统计过慢查询吗?对慢查询都怎么优化过?我们平时写SQL时,都要养成用explain分析的习惯。慢查询的统计,运维会定期统计给我们
优化慢查询思路:
分析语句,是否加载了不必要的字段/数据
分析SQL执行句话,是否命中索引等
如果SQL很复杂,优化SQL结构
如果表数据量太大,考虑分表
三、索引
1、聚集索引与非聚集索引的区别可以按以下四个维度回答:
一个表中只能拥有一个聚集索引,而非聚集索引一个表可以存在多个。
聚集索引,索引中键值的逻辑顺序决定了表中相应行的物理顺序;非聚集索引,索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同。
索引是通过二叉树的数据结构来描述的,我们可以这么理解聚簇索引:索引的叶节点就是数据节点。而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。
聚集索引:物理存储按照索引排序;非聚集索引:物理存储不按照索引排序;
2、为什么要用B+树,为什么不用普通二叉树?可以从几个维度去看这个问题,查询是否够快,效率是否稳定,存储数据多少,以及查找磁盘次数,为什么不是普通二叉树,为什么不是平衡二叉树,为什么不是B树,而偏偏是B+树呢?
1)为什么不是普通二叉树?
如果二叉树特殊化为一个链表,相当于全表扫描。平衡二叉树相比于二叉查找树来说,查找效率更稳定,总体的查找速度也更快。
2)为什么不是平衡二叉树呢?
我们知道,在内存比在磁盘的数据,查询效率快得多。如果树这种数据结构作为索引,那我们每查找一次数据就需要从磁盘中读取一个节点,也就是我们说的一个磁盘块,但是平衡二叉树可是每个节点只存储一个键值和数据的,如果是B树,可以存储更多的节点数据,树的高度也会降低,因此读取磁盘的次数就降下来啦,查询效率就快啦。
3)为什么不是B树而是B+树呢?
B+树非叶子节点上是不存储数据的,仅存储键值,而B树节点中不仅存储键值,也会存储数据。innodb中页的默认大小是16KB,如果不存储数据,那么就会存储更多的键值,相应的树的阶数(节点的子节点树)就会更大,树就会更矮更胖,如此一来我们查找数据进行磁盘的IO次数有会再次减少,数据查询的效率也会更快。
B+树索引的所有数据均存储在叶子节点,而且数据是按照顺序排列的,链表连着的。那么B+树使得范围查找,排序查找,分组查找以及去重查找变得异常简单。
3、Hash索引和B+树索引区别是什么?你在设计索引是怎么抉择的?B+树可以进行范围查询,Hash索引不能。
B+树支持联合索引的最左侧原则,Hash索引不支持。
B+树支持orderby排序,Hash索引不支持。
Hash索引在等值查询上比B+树效率更高。
B+树使用like进行模糊查询的时候,like后面(比如%开头)的话可以起到优化的作用,Hash索引根本无法进行模糊查询。
4、什么是最左前缀原则?什么是最左匹配原则?最左前缀原则,就是最左优先,在创建多列索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。
当我们创建一个组合索引的时候,如(a1,a2,a3),相当于创建了(a1)、(a1,a2)和(a1,a2,a3)三个索引,这就是最左匹配原则。
5、索引不适合哪些场景?数据量少的不适合加索引
更新比较频繁的也不适合加索引=区分度低的字段不适合加索引(如性别)
6、索引有哪些优缺点?1)优点:
唯一索引可以保证数据库表中每一行的数据的唯一性
索引可以加快数据查询速度,减少查询时间
2)缺点:
创建索引和维护索引要耗费时间
索引需要占物理空间,除了数据表占用数据空间之外,每一个索引还要占用一定的物理空间
以表中的数据进行增、删、改的时候,索引也要动态的维护。
四、锁
1、MySQL遇到过死锁问题吗,你是如何解决的?遇到过。我排查死锁的一般步骤是酱紫的:
查看死锁日志showengineinnodbstatus;
找出死锁SQL;
分析SQL加锁情况;
模拟死锁案发;
分析死锁日志;
分析死锁结果;
2、说说数据库的乐观锁和悲观锁是什么以及它们的区别?1)悲观锁:
悲观锁她专一且缺乏安全感了,她的心只属于当前事务,每时每刻都担心着它心爱的数据可能被别的事务修改,所以一个事务拥有(获得)悲观锁后,其他任何事务都不能对数据进行修改啦,只能等待锁被释放才可以执行。
2)乐观锁:
乐观锁的“乐观情绪”体现在,它认为数据的变动不会太频繁。因此,它允许多个事务同时对数据进行变动。
实现方式:乐观锁一般会使用版本号机制或CAS算法实现。
3、MVCC熟悉吗,知道它的底层原理?MVCC(MultiversionConcurrencyControl),即多版本并发控制技术。
MVCC在MySQLInnoDB中的实现主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读。
五、事务
1、MySQL事务得四大特性以及实现原理原子性:事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
一致性:指在事务开始之前和事务结束以后,数据不会被破坏,假如A账户给B账户转10块钱,不管成功与否,A和B的总金额是不变的。
隔离性:多个事务并发访问时,事务之间是相互隔离的,即一个事务不影响其它事务运行效果。简言之,就是事务之间是进水不犯河水的。
持久性:表示事务完成以后,该事务对数据库所作的操作更改,将持久地保存在数据库之中。
2、事务的隔离级别有哪些?MySQL的默认隔离级别是什么?读未提交(ReadUn