(一) 常见的两种存储引擎:MyISAM与InnoDB
1) MyISAM存储引擎的特点:表级锁,不支持事务、外键和全文索引。
2) InnoDB存储引擎的特点:行级锁、事务安全(ACID兼容)、支持外键。
(二) MyISAM与InnoDB的表锁和行锁
1) MySQL表级锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)。什么意思呢,就是说对MyISAM表进行读操作时,它不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写操作;而对MyISAM表的写操作,则会阻塞其他用户对同一表的读和写操作。
2) InnoDB行锁是通过给索引项加锁来实现的,即只有通过索引条件检索数据,InnoDB才使用行级锁,否则将使用表锁!行级锁在每次获取锁和释放锁的操作需要消耗比表锁更多的资源。在InnoDB两个事务发生死锁的时候,会计算出每个事务影响的行数,然后回滚行数少的那个事务。
(三) Innodb的四大特性
1) 插入缓冲(insert buffer):只对于非聚集索引(非唯一)的插入和更新有效,对于每一次的插入不是写到索引页中,而是先判断插入的非聚集索引页是否在缓冲池中,如果在则直接插入;若不在,则先放到Insert Buffer中,再按照一定的频率进行合并操作,再写回disk。这样通常能将多个插入合并到一个操作中,目的还是为了减少随机IO带来性能损耗。
使用插入缓冲的条件:
非聚集索引
非唯一索引
2) 二次写(double write): 对页面拷贝副本,提高数据页的可靠性,当写失效时,通过副本页还原原页,再进行redu。
doublewrite由 内存中的doublewrite buffer (2MB) 和物理磁盘上共享表空间中连续的128个页,即两个区(2MB)组成想
3) 自适应哈希索引(ahi): innodb会监控对表上个索引页的查询。如果观察到建立哈希索引可以带来速度提升,则自动建立哈希索引。
特点
1、无序,没有树高
2、降低对二级索引树的频繁访问资源,索引树高<=4,访问索引:访问树、根节点、叶子节点
3、自适应
3、缺陷
1、hash自适应索引会占用innodb buffer pool;
2、自适应hash索引只适合搜索等值的查询,如select * from table where index_col='xxx',而对于其他查找类型,如范围查找,是不能使用的;
3、极端情况下,自适应hash索引才有比较大的意义,可以降低逻辑读。
4) 预读(read ahead):InnoDB使用两种预读算法来提高I/O性能:线性预读(linear read-ahead)和随机预读(randomread-ahead)。
把线性预读放到以extent为单位,而随机预读放到以extent中的page为单位。
线性预读:当达到innodb_read_ahead_threshold(阈值,默认为56)时,将下一个extent提前读取到buffer pool中,而随机预读着眼于将当前extent中的剩余的page提前读取到buffer pool中。
(四) InnoDB的数据结构
1) 数据行和数据页:数据行之间是以单链表的形式存放的,头尾有两个特殊记录(最小记录数据行和最大记录数据行),而数据页之间以双链表的形式连接,方便快速定位到数据在哪一页上,一个数据页包含多个数据行。
2) B+Tree索引
1. 聚集索引:一颗B+树,叶子节点就是真实数据行所构成的数据页
(了解)最下面那层是根据id排序生成的。最底下那层的叶子节点是真实的数据,有4页,每页里面有一个单链表,就是我们的真实数据行。第二行有两页,每页中也是有个数据行构成的单链表,这是的数据行只包含了页码(最底下那层某页)、某页最大id,由此可见,第二行比最底下那行页数少了很多很多。就这样,一层一层的抽取,一定会有一个所谓的跟页。我们搜索数据就是从跟页开始的,一层一层往下找的。页内是单链表,同层的页和页之间是双链表。
2. 二级索引:即自己建立索引,比如给age添加索引。而树的叶子节点保存的是该age属性和主键id,非叶子节点存的是页码和下面那层某页的最大的age值,找到对应的id值后需要回表(拿着主键回去聚集索引找)。
3. 联合索引:特殊的二级索引,比如给(name,age)添加联合索引,底层数据结构和普通二级索引没什么区别,只不过叶子节点存的是name、age和主键id,非叶子节点存的是页码和下面那层最大的name值,所以如果搜索条件只有age,没有name的话,联合索引会失效,即遵循最左原则。
(五) B+树:是b树的一种变体,查询性能更好。
1) 有n棵子树的非叶子结点中含有n个关键字(b树是n-1个),这些关键字不保存数据,只用来索引,所有数据都保存在叶子节点(b树是每个关键字都保存数据)。
2) 所有的叶子结点中包含了全部关键字的信息,及指向含这些关键字记录的指针,且叶子结点本身依关键字的大小 自小而大 顺序链接。
3) 所有的非叶子结点可以看成是索引部分,结点中仅含其子树中的最大(或最小)关键字。
4) 通常在b+树上有两个头指针,一个指向根结点,一个指向关键字最小的叶子结点。
5) 同一个数字会在不同节点中重复出现,根节点的最大元素就是b+树的最大元素。
(六) 为什么选用B+树作为数据库的索引结构:
1) B+树的中间节点不保存数据,是纯索引,但是B树的中间节点是保存数据和索引的,相对来说,B+树磁盘页能容纳更多节点元素,更“矮胖”;
2) B+树查询必须查找到叶子节点,B树只要匹配到即可不用管元素位置,因此b+树查找更稳定(并不慢);
3) 对于范围查找来说,B+树只需遍历叶子节点链表即可,B树却需要重复地中序遍历,在项目中范围查找又很是常见的
4) 增删文件(节点)时,效率更高,因为B+树的叶子节点包含所有关键字,并以有序的链表结构存储,这样可很好提高增删效率。