1. 慢查询问题
1.1 如何定位慢查询
- 开源工具
- Arthas ------调试工具
- Promtheus Skywalking ------运维工具
- Mysql自带的慢日志
- 配置文件中开启慢日志:slow-query-log = 1
- 设置慢日志时间 long-query-time = 2
1.2.Sql语句分析
- 通过 explain 关键字--在执行语句前面加上explain
- 含义
- 如何分析该段Sql
2.索引
2.1.什么是索引,索引的底层数据结构
- 索引
- 索引时帮助Mysql快速寻找数据的一种数据结构
- 底层数据结构
- Mysql索引底层韦B+树(旨在叶子节点上存放数据(一般为信息的逻辑地址))。
2.2 聚簇索引与非聚簇索引
- 聚簇索引:每个表都有,且只有一个,表数据按照索引键的顺序存储,索引的叶子节点就是数据页本身,一般为主键索引
- 非聚簇索引:独立于数据行的单独结构,一个表可以有多个,索引的叶子节点包含数据行的指针,查询需要回表查询
2.3 回表查询
2.4 覆盖索引
- 查询用到了索引,且返回的数据在该索引中都存在,如果返回的列中有没有创建索引的数据,则会进行回表查询
2.5 索引创建的原则
- 数据量大,且查询频繁的表
- 常作为查询条件,排序,分组的列
- 字段区分度高
- 尽量使用联合索引,索引占用空间
- 控制索引 数量
- 如果索引列不能存储null,在创建表时NOT NULL约束
2.6 索引失效
- 联合索引必须符合最左前缀法则
- 范围查询右边的列不能使用索引
- 不要在索引上进行运算操作
- 类型转换导致索引失效
- 模糊查询,%在前索引失效,%在后不会导致
3 Sql优化
3.1 表的设计优化与SQL语句优化
- 表的设计优化,数据类型的选择
- 索引优化,索引创建原则
- Sql语句优化,避免索引失效,避免使用select *
- 主从复制,读写分离,不让写的数据影响读的数据
- 分库分表
4 Mysql事务
- 原子性
- 事务是不可分割的最小单元,必须全部成功或失败
- 一致性
- 事务完成时,所有数据状态一致
- 持久性
- 一但事务提交或者回滚,对数据库的影响时永久的
- 隔离性
- 事务不受外部并发操作影响
4.1 并发事务问题
- 脏读
- 一个事物读取到另一个事务未提交的数据
- 不可重复读
- 一个事务前后两次读取同一数据结果不一致
- 幻读
- 一个事物读取数据是,发现数据不存在,但在添加数据时,发现这一数据又出现了
4.1.1 隔离级别
- 未提交读
- 允许事务读取其他未提交的事务------脏读
- 读已提交
- 只允许读取已提交的数据------通过读取时加共享锁,读后释放锁------解决脏读
- 可重复读(Mysql默认隔离级别)
- 确保同一事物读取同一数据结果相同------通过锁定读取行,读取时加共享锁,事务后释放锁------解决读已提交
- 串行化
- 完全串行执行命令,不存在并发问题------加范围锁
4.2 redo log
- 重做日志,用来记录事务提交时数据页物理的修改,用来实现事务的持久性
- redo log buffer------重做日志缓冲,内存
- redo log file------重做日志文件,磁盘
4.3 undo log
- 回滚日志,用于记录数据被修改前的信息
- 作用
- 提供回滚
- Mvcc
- 当delete时,undo log记录一个insert,反之亦然
- 当update,记录一条相反的update,当执行rollback时,可以从undo log中读取相应的内容。
- undo log 可以实现事务的一致性和原子性
- 作用
5 MVCC
5.1 实现原理
- 通过表中隐藏字段
- 隐藏主键(没创建主键的情况)
- 事务ID:最后一条修改该记录的事务Id
- 回滚指针:指向这条记录的上一个版本,用于配合undo log ,实现了一条记录的一个版本链
- 实现原理
-
readView
- 这是快照读Sql执行时Mvcc提取数据的重要依据,记录并维护当前活跃的事务(未提交)的ID
- 关键字段
- m_ids:当前活跃事务ID集合
- min_trx_id:最活跃小事务ID
- max_trx_id:最大事务ID➕1,预分配事务ID
- creator_trx_id:ReadView创建者事务ID
-
当前读
- 读取的时最新版本的数据,读取时还要保证其他事务不能并发修改当前的记录,会对读取的记录加锁,
-
快照读
- 简单的seclet 就是快照读,不加锁
- Read Committed : 每次seclet都生成一个快照
- Repeatable Read : 开启事务的第一个select语句才生成一个快照
-
6.MYSQL主从同步
- Master主库在事务提交时,会将变更记录在binglog(二进制日志文件)中。
- 从库从主库的binlog(二进制日志文件)中读取,写入到从库的Relaylog(中继日志文件)。
- 从库(slave)重新复现中继日志中的文件。
7.分库分表
7.1拆分策略
-
垂直
- 垂直分库:以表唯依据,根据不同业务将不同表分到不同的库(微服务的各模块的数据库)
- 垂直分表:以字段为依据,将属性不同的字段拆分到不同的表中
- 拆分规则:
- 将不常用的字段单独拆分
- 将text,blob 等大字段拆分
- 拆分规则:
-
水平
- 水平分库:将一个库的数据拆分到多个库中。(类似于集群)
- 路由规则;
- 根据id取模
- 按id范围路由。
- ...
- 路由规则;
- 水平分表:将一个表中数据拆分到多个表中。
- 水平分库:将一个库的数据拆分到多个库中。(类似于集群)
-