MySQL经典面试题
MySQL经典面试题
优化
在MySQL中,如何定位慢查询?
慢查询情况:
- 聚合查询
- 多表查询
- 表数据量过大查询
- 深度分页查询
表象:页面加载过慢、接口压测响应时间过长(超过1s)
方案一:开源工具
- 调试工具:Arthas
- 运维工具:Prometheus、Skywalking
方案二:MySQL自带慢日志
慢查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10秒)的所有SQL语句的日志。
如果要开启慢查询日志,需要在MySQL的配置文件(/etc/my.cnf)中配置如下信息:
1
2
3
4#开启MySQL慢日志查询开关
slow_query_log=1
#设置慢日志的时间为2秒,SQL语句执行时间超过2s,就会视为慢查询,记录慢查询日志
long_query_time=2
面试话术:

生产条件下不会开启慢日志,会损耗一些MySQL的性能

SQL语句执行计划
可以采用EXPLAIN或者DESC命令获取MySQL如何执行SELECT语句的信息

possible_key:当前sql可能会使用到的索引
key:当前sql实际命中的索引
key_len:索引占用的大小
通过key和key_len两个查看是否可能会命中索引,索引本身存在是否有失效的情况
Extra:额外的优化建议

是否出现了回表,如果出现了,可以尝试添加索引或修改返回字段来修复
type:这条sql的连接的类型,性能由好到差为NULL、system、const、eq_ref、ref、range、index、all
NULL:这条sql语句执行时没有用到表
system:查询系统中的表
const:根据主键查询
eq_ref:主键索引查询或唯一索引查询,只能返回一条
ref:索引查询,可能是多条
range:范围查询
index:索引树扫描
all:全盘扫描
如果是index或all,就需要优化


什么是索引
索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库还维护着满足特定查找算法的数据结构(B+树),这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。
数据结构对比



非叶子节点存储指针,效率更高,磁盘读写代价低;数据都存储在叶子节点上,查询效率稳定;且叶子节点之间存在链表,适合扫库和区间查询


什么是聚簇索引,什么是非聚簇索引(二级索引)/什么是回表查询
聚簇索引和二级索引
自己创建的索引一般都是二级索引


回表查询

回表查询:先通过二级索引拿到主键值,再根据主键值通过聚集索引拿到整行数据。


什么是覆盖索引
指查询中使用了索引,并且需要返回的列,在该索引中已经全部能够找到


MySQL超大分页处理




索引创建原则有哪些



什么情况下索引会失效
联合索引中每个索引字段存在顺序

通过执行计划explain判断哪块索引失效
- 违反最左前缀法则
- 如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始,并且不跳过索引中的列。
- 如果符合最左法则,但是出现跳跃某一列,只有最左列索引生效
- 可以理解为联合索引中,从哪一个索引开始在sql语句中where后面的判断语句部分没出现,那么从它开始(包括自己)的索引都失效
- 范围查询的右边的列,不能使用索引
- 可以理解为联合索引中,从哪一个索引开始在sql语句中where后面的判断语句部分是通过大于小于号进行范围查询的,那么从它下一个索引开始的索引都失效(即范围查询的这个索引不失效,而是下一个开始失效)
- 不要在索引列上进行运算操作,索引将失效
- 比如substring
- 字符串不加单引号,造成索引无效
- 由于MySQL的查询优化器会自动的进行类型转换,造成索引无效
- 以%开头的Like模糊查询,索引失效。如果仅仅是尾部模糊查询匹配,索引不会失效。如果是头部模糊匹配,索引失效。
- 即%xxx会失效,xxx%则不会失效

SQL优化经验

第四点中,union all查询后两个条件查询出来的数据合并,所以会有重复的数据;而union查询后自动查重,不会有重复数据。
第五点中,
小循环放外面,MySQL就只需要3次的数据库连接,再在里面进行1000次的数据操作就可以了.


其他
事务相关
事务的特性是什么
事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。
- 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
- 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
- 隔离性(Isolution):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
- 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。

并发事务带来哪些问题?怎样解决?MySQL的默认隔离级别?
- 并发事务问题:脏读、不可重复读、幻读
- 隔离级别:读未提交、读已提交、可重复读、串行化


事务B读到的是事务A中更改的数据,但是事务A还未提交

在事务A两次读操作中间事务B进行了数据的修改,导致两次读操作读到的内容不一致

在解决了不可重复读的前提下,事务A读数据库发现没有这条数据,这时事务B插入了这条数据,导致A插入时报错,A再读时还是显示数据库中没有,可是插不进去
解决方案:对事物进行隔离

解决了问题是×,还有这种问题是√
注意:事务隔离级别越高,数据越安全,但是性能越低

undo log和redo log的区别


如果服务器出问题了,内存中修改的内容无法同步给服务器,不符合事务的持久性。
redo log:

undo log:


解释一下MVCC?/事务中的隔离性是如何保证的?

全程Multi-Version Concurrency Control,多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突。
MVCC的具体实现,主要依赖于数据库记录中的隐式字段、undo log日志、readView。

记录中的隐藏字段

undo log


readView
ReadView(读视图)是快照读SQL执行时MVCC提取数据的依赖,记录并维护系统当前活跃的事务(未提交的)id。


MVCC的实现原理

当前未提交的事务是活跃的事务



从后往前依次根据标准判断,第一个符合的就是使用的记录




主从同步原理

MySQL主从复制的核心就是二进制日志


分库分表
分担了访问压力,解决存储压力
分库分表的时机:
- 前提,项目业务数据逐渐增多,或业务发展比较迅速(单表的数据量达1000W或20G以后)
- 优化已解决不了性能问题(主从读写分离、查询索引……)
- IO瓶颈(磁盘IO、网络IO)、CPU瓶颈(聚合查询、连接数太多)
拆分策略





新的问题和新的技术






