作者:
逍遥Sean
简介:一个主修Java的Web网站\游戏服务器后端开发者
主页:https://blog.csdn.net/Ureliable
觉得博主文章不错的话,可以三连支持一下~ 如有需要我的支持,请私信或评论留言!
索引⽤来快速地寻找那些具有特定值的记录。如果没有索引,⼀般来说执⾏查询时遍历整张表。
索引的原理:就是把⽆序的数据变成有序的查询
查询更快、占⽤空间更⼩
事务基本特性ACID分别是:
原⼦性: 指的是⼀个事务中的操作要么全部成功,要么全部失败。
⼀致性: 指的是数据库总是从⼀个⼀致性的状态转换到另外⼀个⼀致性的状态。⽐如A转账给B 100块钱,假设A只有90块,⽀付之前我们数据库⾥的数据都是符合约束的,但是如果事务执⾏成功了,我们的数据库数据就破坏约束了,因此事务不能成功,这⾥我们说事务提供了⼀致性的保证
隔离性: 指的是⼀个事务的修改在最终提交前,对其他事务是不可⻅的。
持久性: 指的是⼀旦事务提交,所做的修改就会永久保存到数据库中。
隔离性有4个隔离级别,分别是:
read uncommit 读未提交,可能会读到其他事务未提交的数据,也叫做脏读。⽤户本来应该读取到id=1的⽤户age应该是10,结果读取到了其他事务还没有提交的事务,结果读取结果age=20,这就是脏读。read commit 读已提交,两次读取结果不⼀致,叫做不可重复读。不可重复读解决了脏读的问题,他只会读取已经提交的事务。⽤户开启事务读取id=1⽤户,查询到age=10,再次读取发现结果=20,在同⼀个事务⾥同⼀个查询读取到不同的结果叫做不可重复读。repeatable read 可重复复读,这是mysql的默认级别,就是每次读取结果都⼀样,但是有可能产⽣幻读。serializable 串⾏,⼀般是不会使⽤的,他会给每⼀⾏读取的数据加锁,会导致⼤量超时和锁竞争MVCC(Multi-Version Concurrency Control ,多版本并发控制)指的就是在使⽤READ COMMITTD、REPEATABLE READ这两种隔离级别的事务在执⾏普通的SEELCT操作时访问记录的版本链的过程。可以使不同事务的读-写、写-读操作并发执⾏,从⽽提升系统性能。
READ COMMITTD、REPEATABLE READ这两个隔离级别的⼀个很⼤不同就是:⽣成ReadView的时机不同,READ COMMITTD在每⼀次进⾏普通SELECT操作前都会⽣成⼀个ReadView,⽽REPEATABLEREAD只在第⼀次进⾏普通SELECT操作前⽣成⼀个ReadView,之后的查询操作都重复使⽤这个ReadView就好了。
MyISAM:
InnoDb:
| 列名 | 描述 |
|---|---|
| id | 查询语句中每出现⼀个SELECT关键字,MySQL就会为它分配⼀个唯⼀的id值,某些⼦查询会被优化为join查询,那么出现的id会⼀样 |
| select_type | SELECT关键字对应的那个查询的类型 |
| table | 表名 |
| partitions | 匹配的分区信息 |
| type | 针对单表的查询⽅式(全表扫描、索引) |
| possible_keys | 可能⽤到的索引 |
| key | 实际上使⽤的索引 |
| key_len | 实际使⽤到的索引⻓度 |
| ref | 当使⽤索引列等值查询时,与索引列进⾏等值匹配的对象信息 |
| rows | 预估的需要读取的记录条数 |
| filtered | 某个表经过搜索条件过滤后剩余记录条数的百分⽐ |
| Extra | ⼀些额外的信息,⽐如排序等 |
索引覆盖就是⼀个SQL在执⾏时,可以利⽤索引来快速查找,并且此SQL所要查询的字段在当前索引对应的字段中都包含了,那么就表示此SQL⾛完索引后不⽤回表了,所需要的字段都在当前索引的叶⼦节点上存在,可以直接作为结果返回了
当⼀个SQL想要利⽤索引是,就⼀定要提供该索引所对应的字段中最左边的字段,也就是排在最前⾯的字段,⽐如针对a,b,c三个字段建⽴了⼀个联合索引,那么在写⼀个sql时就⼀定要提供a字段的条件,这样才能⽤到联合索引,这是由于在建⽴a,b,c三个字段的联合索引时,底层的B+树是按照a,b,c三个字段从左往右去⽐较⼤⼩进⾏排序的,所以如果想要利⽤B+树进⾏快速查找也得符合这个规则
B树的特点:
Mysql索引使⽤的是B+树,因为索引是⽤来加快查询的,⽽B+树通过对数据进⾏排序所以是可以提⾼查询速度的,然后通过⼀个节点中可以存储多个元素,从⽽可以使得B+树的⾼度不会太⾼,在Mysql中⼀个Innodb⻚就是⼀个B+树节点,⼀个Innodb⻚默认16kb,所以⼀般情况下⼀颗两层的B+树可以存2000万⾏左右的数据,然后通过利⽤B+树叶⼦节点存储了所有数据并且进⾏了排序,并且叶⼦节点之间有指针,可以很好的⽀持全表扫描,范围查找等SQL语句。
按锁粒度分类:
- ⾏锁:锁某⾏数据,锁粒度最⼩,并发度⾼
- 表锁:锁整张表,锁粒度最⼤,并发度低
- 间隙锁:锁的是⼀个区间
还可以分为:
- 共享锁:也就是读锁,⼀个事务给某⾏数据加了读锁,其他事务也可以读,但是不能写
- 排它锁:也就是写锁,⼀个事务给某⾏数据加了写锁,其他事务不能读,也不能写
还可以分为:
- 乐观锁:并不会真正的去锁某⾏记录,⽽是通过⼀个版本号来实现的
- 悲观锁:上⾯所的⾏锁、表锁等都是悲观锁
在事务的隔离级别实现中,就需要利⽤锁来解决幻读