一.体系
1.索引
2.锁
3.事务
二.索引
1.存储
索引底层使用B+树存储。
B+树除叶子结点存储数据,中间层结点不存储数据。这样做优点:
1.索引树较小,能加载到内存,按索引搜索会快,否则有部分索引树在磁盘就会拖慢整体搜索效率。
2.整体搜索时间比较平均
如果是数据在每个索引结点,因为不同数据大小是不一样的,导致有些数据的查询非常快(在树的中间部分就查到,但有些数据可能在树的底层,导致查询时间相差大)。
3.更利于范围查询
要查询5到20的数据,B树要做中序遍历(因为数据存储在树中每一个结点中)。
而B+树只需要先定位到相应的5的最下面的叶子结点,然后在叶子结点这层按序扫描就可以了。
性能更高。
2.索引分类
有聚簇索引与非聚簇索引之分。
聚簇索引相应的叶子结点就包含了想要查询的数据。主键索引就是聚簇索引。
其它的都是非聚簇索引。非聚簇索引的叶子结点上存储的是主键的索引id,所以非聚簇索引查询需要至少3次以上:一次非聚簇索引的叶子结点定位需要n次,查询对应聚族索引的叶子结点,然后再从聚簇索引叶子结点上指向的指针去查询磁盘数据。
三.锁
基于innodb:
1.分类
1.1.按是否排它性维度
共享锁,排它锁,意向共享锁,意向排他锁。
意向共享及意向排他锁是mysql内部的,主要是为了提升全表锁与行级锁共存时加全表锁的性能。
没有意向锁的情况下,如果要加全表共享或全表排他锁,就需要扫描索引树中看是否存在相应的行级锁,这个性能会很低。
共享锁场景:
select * from table1 where id=1 lock in share mode。
排他锁场景:
select * from table 1 where id=2 for update。
或update,insert,delete语句会默认加排他锁。
共享锁加了后,其它线程可以读,但不能再做修改,也不能再加排他锁了。
1.2.按锁粒度
表级锁:
ddl,或select for update时,无索引的情况下。
行级锁:
行记录锁就是锁在行记录上。
区间锁:
gap锁及next key锁则只是在可重复读的事务级别下才会有。
gap锁及next key锁都是解决幻读。
gap锁锁定一个区间,不包含记录本身。eg: select * from tabel1 where id>5 and id<10;
next key锁锁定记录及区间。eg: select * from tabel1 where id=5;
四.事务
数据库事务中有以下几个问题:
脏读,不可重复读及幻读。
为了解这几个问题,事务隔离级别有以下几个:
读未提交(RU):会出现脏读,不可重复读,幻读。
读已提交(RC):能解脏读。
可重复读(RR): 能解脏读,不可重复读 ,幻读(mysql特有)
串形化: 会出现脏读,不可重复读,幻读
注:
mysql通过mvcc机制在RR隔离级别下解决了幻读问题。