MySQL

143 阅读6分钟

索引 慢查询 MVCC 表设计(三范式 隔离级别(问题 事务传递

索引失效
包含<>
like查询以%开头
索引列参与计算
索引列隐式转换
组合索引违背最左匹配原则
not in
not exist
建表注意事项
一个对象一张表,表职能单一
遵循三范式
适当反第三范式,添加冗余字段,减少连表查询
建立适当的索引:如外键关系索引
不创建外键关联,只有外键关系
选用合适的字段,选用可以存储值最小的字段,int比varchar在mysql中存储的少,尽量定义not null字段,text尽量不用
表字段类型统一:外键类型大小一致,金额decimal,状态tinyint,时间datetime
参考

什么时候建立索引?

什么时候建立索引?
作为外键关联的字段
数据量大
频繁用于查询的字段
group by,order by字段
建立索引时注意什么?选什么字段建立索引?
表数据量大时要建立索引
区分度高的列建立
多作为查询条件的列建立索引
order by, group by 列建立索引
什么情况不建议建立索引
数据量少的表
更新频繁的字段
区分度低的字段

MySQL底层B+tree

MySQL隔离级别--》对应的异常数据

隔离级别
读未提交
读已提交
可重复读MySQL默认级别
串行化
问题
脏读
不可重复读
幻读

MySQL的ACID特性

标题
原子性
隔离性
一致性
持久性

MVCC多版本并发控制-快照读,当前读

MySQL InnoDB存储引擎,实现的是多版本并发控制MVCC

MVCC的实现:是通过保存某一个时间点的快照来实现的

MVCC并发-多操作
快照读读取的是记录的可见版本(有可能是历史版本)不用加锁(共享锁也不加,不会阻塞其他事务的写)
当前读读取的是记录的最新版本,返回当前记录,都会加锁,保证其他事务不会并发修改该记录
MVCC&BLCC
多版本并发控制MVCC优点:读不加锁,读写不冲突
基于锁的并发控制BLCC纯粹基于锁的并发机制并发量低,MVCC是基于锁的并发控制上的改进,主要是在读操作上提高了并发量(快照读

mvcc讲解非常nice juejin.cn/post/688605… segmentfault.com/a/119000001…

MVCC是如何实现的?

为了实现MBCC机制,InneDB内部为每一行添加了两个隐藏列:事务ID,回滚指针。另外MYSQL另外还有一个隐藏列行ID,就是在InnerDB表没有主键的时候会用来作为主键。 事物ID长度为六个字节,存储了插入或更新语句的最后一个事物的事物ID。 回滚指针长度为七个字节,称为回滚指针,回滚指针指向写入回滚段的undo log记录读取记录的时候会根据指针去读取undo中的记录。正因为MYSQL中ondo log中会维护一个历史数据记录,所以我们应该养成定期提交事物的习惯,否则回滚段会越来越大,甚至占满了表空间。

MCC查询两大规则
只查询事物ID小于等于当前事物ID的数据
二只查询未删除回滚指针为空或者回滚指针大于当前事物ID的数据
数据库三范式
字段不可拆分有主键,其他字段必须依赖主键其他字段必须直接依赖主键,非主键字段不能相互依赖

MySQL索引

优缺点
优点
提高查询速度
使用Btree索引时,可范围查询
缺点
占用磁盘空间
损耗性能,增/删/改需要动态维护
分类
普通vs唯一
普通索引可重复,可有多个null
唯一索引不可重复,可有一个null
主键索引不可重复,没有null
单列vs组合
单列索引只有一列
组合索引多列,只有在查询时,使用了这些字段的左边字段时,才走索引
覆盖索引多列索引的特例,查询的列都在索引中,不需要回表
最左匹配原则多列索引最左匹配原则
聚簇vs非聚簇
聚簇索引每个表有且只有一个聚簇索引,整个表的数据存储在聚簇索引中,叶子节点存储主键值及对应记录,非叶子节点不存储数据
非聚簇索引除了聚簇索引,其他的都是非聚簇索引,非聚簇索引叶子节点存储索引字段值及主键
全文索引支持全文查找,允许重复,null;可以在char,varchar,text创建全文索引;MySQL只有MyISAM存储引擎支持全文索引
索引常见问题
回表在非聚簇索引中找到对应的主键id,再到聚簇索引中找到对应的记录
索引覆盖
索引下推
设计原则
多用于查询条件的列
多用于排序,分组的列
数据量大的表
外键关联id
区分度高的列建立索引(如性别就不需要索引)
联合索引注意最左匹配原则,MySQL会一直向右匹配,直到遇到范围查询
juejin.cn/post/697641…
索引面试题
什么是最左匹配原则
为什么使用B+tree做索引,而不用hash做索引1.模糊查询,2.范围查询,3.哈希碰撞
主键索引与非主键索引有什么区别
为什么建议使用主键自增
SQL优化建议

慢SQL

explain语法
类型描述
select_typeselect查询类型,simple-简单(不使用union或子查询),primary-主查询,union-联合查询,subquery-子查询,等
table
parttions
type本数据表与其他数据表之间的关联关系,system,const,eq_ref,ref,range,index,all
possible_keys
key
key_len
ref
rows
filtered
extra估计要读取的行【extra】
Using index:使用覆盖索引,表示查询索引就可查到所需数据,不用扫描表数据文件,往往说明性能不错。
Using Where:在存储引擎检索行后再进行过滤,使用了where从句来限制哪些行将与下一张表匹配或者是返回给用户。
Using temporary:在查询结果排序时会使用一个临时表,一般出现于排序、分组和多表 join 的情况,查询效率不高,建议优化。
Using filesort:对结果使用一个外部索引排序,而不是按索引次序从表里读取行,一般有出现该值,都建议优化去掉,因为这样的查询
CPU 资源消耗大。
blog.csdn.net/Python_BT/a…
常见慢sql优化 blog.csdn.net/TABE_/artic…

like查询优化 blog.csdn.net/Martin_chen… www.jianshu.com/p/efeec2215…

limit分页优化www.cnblogs.com/huaweiyun/p…

数据库优化维度 参考
硬件
系统
表结构1.使用可以存储下数据的最小数据类型;2.使用简单的数据类型,int比varchar在MySQL上处理简单;3.尽可能使用not null定义字段;4.尽量少用text,非用不可时考虑分表
SQL优化