1、Mysql的undo log、redo log、binlog有什么用?
undolog、redo log只适用于InnoDB,用来支持事务。
redo(重做日志):崩溃恢复、数据持久化。保障事务持久性
undo (回退日志):事务修改前的记录,如果事务回滚,从undo中找到相应记录撤销事务所做更改。MVCC。保障事务原子性,一致性。
binlog用来记录所有DDL、DML语句的一种二进制文件。数据备份、崩溃恢复、数据复制
2、事务的特性?
原子性:
- 对数据的修改,要么全都执行,要么全都不执行。
一致性:
- 在事务开始和完成时,数据都必须保持一致状态。
持久性:
- 事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。
隔离性:
- 数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。这意味着事务处理过程中的中间状态对外部是不可见的,反之亦然。
3、并发事务处理带来的问题?
脏写:
多个事务更新同一行,最后的更新覆盖了由其他事务所做的更新。
脏读:
事务A读取到了事务B已经修改但尚未提交的数据,还在这个数据基础上做了操作。此时,如果B事务回滚,A读取的数据无效,不符合一致性要求。
不可重读
事务A内部的相同查询语句在不同时刻读出的结果不一致,不符合隔离性
幻读:
事务A读取到了事务B提交的新增数据,不符合隔离性
幻读和不可重复读的区别
幻读和不可重复读的主要区别在于它们关注的数据变化类型不同。不可重复读主要关注的是同一条数据的值发生变化,而幻读则关注的是查询结果中的记录数量发生变化。具体来说:
-
不可重复读:强调的是同一条数据被修改。例如,事务A读取行x=100,事务B将x更新为200并提交,事务A再次读取x时发现其值变为200。23
-
幻读:强调的是查询结果中的记录数量变化。例如,事务A执行SELECT * FROM table WHERE id > 5,返回n条记录。事务B插入一条id=6的记录并提交,事务A再次执行相同的查询时,返回的记录数变为n+1条
4.MySQL的幻读是怎么被解决的?
https://zhuanlan.zhihu.com/p/411779472
select被MVCC解决,快照读,生成ReadView。
update、insert、delete是当前读。
select for update会加锁,也解决了幻读问题。
Innodb 引擎为了解决「可重复读」隔离级别使用「当前读」而造成的幻读问题,就引出了 next-key 锁,就是记录锁和间隙锁的组合。
5、索引
索引是帮助Mysql高效获取数据的排好序的数据结构。
B+ Tree 非叶子节点只存储索引,可以放更多索引
叶子节点包含所有索引字段
叶子节点用指针连接,提高区间访问性能。
为什么不用hash?hash只能满足= in,不支持范围查询。hash冲突问题。
聚集索引:
- 聚集索引可以一次查到需要查找的数据,而通过非聚集索引第一次只能查到记录对应的主键值再去聚簇索引中查询所需要的记录,这个过程称为回表。正是由于如此,所以通常来说聚簇索引的查询效率要比非聚簇索引高。
- 聚集索引一张表只能有一个,而非聚集索引一张表可以有多个
索引设计原则
1、代码先行,索引后上
2、联合索引尽量覆盖条件
3、不要在小基数字段上建立索引
4、长字符串我们可以采用前缀索引
尽量对字段类型较小的列设计索引,比如说什么tinyint之类的,因为字段类型较小的话,占用磁盘空间也会比较小,此时你在搜索的时候性能也会比较好一点。
当然,这个所谓的字段类型小一点的列,也不是绝对的,很多时候你就是要针对varchar(255)这种字段建立索引,哪怕多占用一些磁盘空间也是有必要的。
对于这种varchar(255)的大字段可能会比较占用磁盘空间,可以稍微优化下,比如针对这个字段的前20个字符建立索引,就是说,对这个字段里的每个值的前20个字符放在索引树里,类似于 KEY index(name(20),age,position)。
此时你在where条件里搜索的时候,如果是根据name字段来搜索,那么此时就会先到索引树里根据name字段的前20个字符去搜索,定位到之后前20个字符的前缀匹配的部分数据之后,再回到聚簇索引提取出来完整的name字段值进行比对。
但是假如你要是order by name,那么此时你的name因为在索引树里仅仅包含了前20个字符,所以这个排序是没法用上索引的, group by也是同理。所以这里大家要对前缀索引有一个了解。
5、where与order by冲突时优先where
6、基于慢sql查询做优化
可以根据监控后台的一些慢sql,针对这些慢sql查询做特定的索引优化。
索引数量不高于5个
索引字段尽量短