Go面试之MySQL总结(一)
图片来源于网络,如有侵权请联系我删除。
面试总结是我个人通过查询资料和开发经验进行的总结,若有错误,请指出,万分感谢。
MySQL架构
-
server层:连接器、分析器、优化器、执行器 -
存储引擎层,比较有名引擎包括:innodb、myisam、memory
SQL查询语句的执行
-
连接器->查询缓存(8.0版本已废弃)->分析器->优化器->执行器 -
rows_examined 的字段,表示这个语句执行过程中扫描了多少行 -
查询缓存在每次表数据更新的时候就会清除缓存
SQL更新语句的执行
-
连接器->分析器->优化器->执行器->存储引擎->执行器->存储引擎 -
执行器操作存储引擎获取要执行的记录 -
拿到记录后执行器对指定字段的结果进行更改 -
执行器调用存储引擎进行数据更改,存储引擎将数据写到内存,并且记录redolog,日志记录的状态为prepare -
执行器生成操作的binlog日志, 执行器调用事务提交接口,引擎将刚刚写入的redolog改成commit状态
执行器SQL更改流程
-
redo log 的写入拆成了两个步骤:prepare 和 commit,这就是"两阶段提交"。 -
redolog和binlog的区别 -
redolog是引擎层的日志,innodb独有的 -
binlog是server层的日志,所有引擎都可以使用 -
redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。 -
redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。 -
Binlog有两种模式,statement 格式的话是记sql语句, row格式会记录行的内容,记两条,更新前和更新后都有。 -
事务
-
事务的特性
-
原子性 -
隔离性 -
一致性 -
持久性
-
事务的隔离级别
-
读未提交,在一个事务里可以读取其他事务未提交的数据变更 -
读提交,在一个事务里只能读取已提交事务的变更数据 -
可重复性读,在一个事务里可以多次读取到当前事务第一次读取的数据 -
串行化,一个事务结束,另一个事务才能继续操作
隔离级别越高,并发性越低,安全性越高
幻读:第一次查询不存在,然后insert失败,这个时候出现了幻读,串行化没幻读,其余都有
-
事务隔离的实现
-
每条记录在更新的时候都会记录一条回滚操作,回滚日志(undolog)在没有比这个版本更老的视图的时候进行删除 -
同一个记录在系统中存在多个版本,也就是多版本并发控制(MVCC) -
尽量避免使用长事务,长事务会占用较大的磁盘空间,长事务占用大量的锁资源,会拖垮整个库。长事务是指执行时间长的SQL变更 -
避免长事务,设置SQL语句操作超时时间、开启自动提交、避免只读事务 -
事务默认都是开启的,可以通过 set autocommit=0
配置进行关闭 -
可以通过显示的命令开启事务 -
索引
索引的出现其实就是为了提高数据查询的效率,就像书的目录一样
-
常见的索引数据结构
-
哈希,适用于精确查询,范围查询效率贼低 -
哈希冲突时使用链表把相同hash的值搞在一块 -
有序数组,在等值查询和范围查询场景中的性能就都非常优,但是在更新数据时效率太低 -
树,每一个索引在 InnoDB 里面对应一棵 B+ 树。 -
二叉搜索树:每个节点的左儿子小于父节点,父节点又小于右儿子
-
InnoDB的索引
-
主键索引 -
非主键索引 -
在使用非主键索引查询时,首先要先找到主键索引,然后根据主键索引查到行记录,这个过程称为回表 -
主键索引的B+树的叶子节点存储的是page (页),一个页里面可以存多个行 -
非主键索引的叶子节点存储的是主键 -
基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主键查询。 -
覆盖索引,比如使用普通索引去查询主键字段或普通索引上的字段,则会命中覆盖索引,无需回表,减少了一次扫描索引树。 -
覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。 -
索引遵循最左前缀原则,最左前缀可以是联合索引的最左 N 个字段,也可以是字符串索引的最左 M 个字符 -
自增主键可以避免页分裂,从性能和存储空间方面考量,自增主键往往是更合理的选择 -
主键长度越小,普通索引的叶子节点就越小,普通索引占用的空间也就越小。 -
-
联合索引创建
-
第一原则是,如果通过调整顺序,可以少维护一个索引,那么这个顺序往往就是需要优先考虑采用的。 -
比如字段 a,b在使用时,都会被频繁查询,a的评率更高,一般建议搞一个 (a,b) 和一个(b) -
-
索引下推
-
在使用联合索引时,当命中了最左原则,在MySQL5.6版本以上会根据后续条件的值判断索引值是否符合,减少回表次数
-
索引重建过程
-
主键索引重建,使用 alter table T engine=InnoDB
语句 -
drop主键索引会导致其他索引失效,但drop普通索引不会。
-
索引总结
-
覆盖索引:如果查询条件使用的是普通索引(或是联合索引的最左原则字段),查询结果是联合索引的字段或是主键,不用回表操作,直接返回结果,减少IO磁盘读写读取正行数据 -
最左前缀:联合索引的最左 N 个字段,也可以是字符串索引的最左 M 个字符 -
联合索引:根据创建联合索引的顺序,以最左原则进行where检索,比如(age,name)以age=1 或 age= 1 and name=‘张三’可以使用索引,单以name=‘张三’ 不会使用索引,考虑到存储空间的问题,还请根据业务需求,将查找频繁的数据进行靠左创建索引。 -
索引下推:like 'hello%’and age >10 检索,MySQL5.6版本之前,会对匹配的数据进行回表查询。5.6版本后,会先过滤掉age<10的数据,再进行回表查询,减少回表率,提升检索速度