本篇文章基于黑马程序员速通面试课程,在此之上加入了我自己的理解,希望可以帮到你。
优化
优化是Mysql中的重要部分之一,为什么需要优化,因为有时候Mysql会有“慢查询”
如何定位慢查询
- 采用了运维工具(Skywalking),可以检测出哪一个接口的耗时长
- 在Mysql中开启了慢查询日志,设置值为两秒,一旦sql执行超过两秒就会记录到日志当中。
如何SQL语句执行很慢如何分析
可以采用Mysql自带的工具EXPLAIN
- 通过key和key_len检查是否命中了索引(索引本身是否有失效的情况)
key当前sql实际命中的索引,key_len索引占的大小 - 通过type字段查看sql是否有进一步优化的空间,是否存在全索引扫描或者全盘扫描
- 通过extra建议分析,是否有回表查询,如果出现了,可以尝试添加索引或修改字段来修复
什么是索引
- 索引是帮助Mysql高效获取数据的数据结构
- 提高检索的效率,降低数据库IO成本(不需要全盘扫描)
- 通过索引对数据进行了排序,降低数据排序成本,降低CPU的消耗
我的理解是,索引就是主键,方便定位一列的数据
索引的底层结构
Mysql的InnoDB引擎采用的B+树的数据结构来存储索引
- 阶数更多,路径更短
- 磁盘读写B+树的代价更低,非叶子节点值存储指针,叶子节点存储数据
- B+树方便扫库和区间查询,叶子结点是个双向链表
B+树
先来介绍下B数
再来介绍一下B+树
可以看到,B+树在B数的基础上进行了优化,只在叶子结点储存数据,优化了IO的性能,是sql优化的核心
什么是聚簇(聚集)索引
- 聚簇索引:数据和索引都放在一起(主键),B+树的叶子结点保存了整行的数据,有且只有一个。
- 非聚簇索引(二级索引):数据和索引分开存放,B+树保存对应的主键,可以有多个
什么是回表查询
其实基于聚簇和非聚簇索引就能引出这一点,回表索引就是通过二级索引引出主键,在通过主键查询整列数据的查询,效率比非回表查询低
什么是覆盖索引
覆盖索引指:需要查询的数据在查询条件中可以直接查出来
- 使用id进行查询,直接聚簇查询全包括,就是覆盖索引
- 返回的列中如果没有创建索引,有可能触发回表查询,尽量避免使用select *
索引创建的原则有哪些?
- %数据量大,且查询比较频繁的表
- %常作为查询条件、排序、分组的字段
- 字段内容区分度高
- 内容较长,使用前缀索引
- %尽量联合索引
- %要控制索引的数量
- 如果索引不能存储NULL要设置NOT NULL约束
什么时候索引失效
- 违反最左前缀原则
- 范围查询右边的列,不能用索引
- 不要在索引列上进行运算操作,否则索引将失效
- 字符串不加单引号,造成索引失效(类型转换)
- 以%开头的like模糊查询,索引失效
谈谈对sql优化的经验
-
表的设计优化,数据类型的选择
-
索引优化,索引创建原则
-
sql语句优化,避免索引失效,避免使用select *
-
主从复制,读写分离,不让数据的写入,影响读操作
-
分库分表
事务
事务的特性是什么
事务是一组不可分割单位,整体成功或者失败
ACID是什么
ACID其实就是事务的特点
- 原子性:事务是不可分割的最小操作单元,要么全部成功,要么全部失败
- 一致性:事务完成时,必须所有数据都保持一致状态
- 隔离性:数据库提供的隔离机制,保证事务在不受外部影响的独立环境下运行
- 持久性:事务一旦提交或者回滚,对数据库的改变是永久的
并发事务问题
- 脏读:一个事务读到另一个事务还没提交的数据
- 不可重复读:一个事务先后读取同一条记录,但是两次读取都不一样,称为不可重复读
- 幻读:一个事务按照条件查询数据时,没有对应的数据行,但是插入数据时,又发现这行数据已经不在了,好像出现了“幻觉”
如何解决并发问题
- 未提交读
- 读已提交
- 可重复读
- 串行化
Mysql的引擎
redo log
redo log是重写日志,用于实现事务的持久性。
该日志文件分为两部分:重做日志缓冲,重做日志文件,前者是在内存,后者在磁盘中,当事务提交以后,会把所有信息更新到日志文件中。发生错误时,进行恢复数据使用。
undo log
回滚日志,用于记录数据修改前的信息,作用包含两个:提供回滚和MVCC。undolog和redolog记录物理日志不一样,他是逻辑日志。
- 当进行insert语句时,undo log会记录一条insert,反之亦然
- 当update时,他会记录一条相反的update记录,当执行rollback时,可以从undolog的逻辑记录直接读取到相应的内容并进行回滚。
redo log和undo log的区别
- redo log:记录的是数据页的物理变化,服务宕机可以用来同步数据
- undo log:记录的事逻辑变化,事务回滚时,可以进行逆操作来恢复原来的数据
- redo log保证了事务的持久性,undo log保证了事务的原子性和一致性
MVCC
主从同步原理
Mysql主从复制的核心就是binlog(DDL)语句和DML(数据操控语言)语句
- 主库在事务提交时,会把数据变更记录在二进制日志文件Binlog中
- 从库读取主库的Binlog文件,写入到从库的Relay Log中
- 从库重做中继日志中的事件,完成主从同步
分库分表
分库分表本质上是因为数据量太多,对库或者表进行垂直或者水平的扩建,以此减小单库/表的容量,提升效率