索引
慢查询
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
| explain语法 | |
|---|
| 类型 | 描述 |
| select_type | select查询类型,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优化 | |