InnoDB的关键特性:
- 插入缓冲(insert buffer)
- 两次写(double write)
- 自适应哈希索引(Adaptive Hash Index)
- 异步IO(AIO)
- 刷新临接页(Flush Neighbor Page)
插入缓冲
Insert Buffer
InnoDB存储引擎中,主键是行唯一的标识符,通常应用程序插入行记录是顺序的,所以插入聚集索引一般也是顺序的。
表中的非聚集索引(辅助索引)在进行插入的时候,数据页的存放还按照主键进行顺序存放,但是对于非聚集索引叶子结点的插入就不在是顺序的,这时候需要离散的访问非聚集索引,由于随机读取的存在而导致了插入操作的性能下降。(在一般情况下辅助索引是比较顺序的)。
InnoDB设计了Insert Buffer,对于非聚集索引的插入或者更新操作,不是每一次直接插入到索引页中,而是先判断插入的非聚集索引页是否在缓冲池中,如果在直接插入,如果不在,则先放入到一个Insert Buffer对象中。然后再以一定的频率和情况进行Insert Buffer和辅助索引叶子节点的Merge(合并)操作,通常能将多个插入缓冲合并到一个操作中(因为在一个索引页中),这就大大提高了非聚集索引插入的性能。
使用Insert Buffer需要满足的条件:1.索引是辅助索引;2.索引不是unique索引
Change Buffer
1.0以后的版本引入了Change Buffer,对数据库DML操作(insert,update,delete)都进行缓冲。分别是Insert Buffer、Delete Buffer、Purge Buffer
使用的满足要求依然是辅助索引且不唯一。
对一条记录的Update操作分为两个过程:
- 将记录标记为已删除
- 真正的记录删除
Merge Insert Buffer
将insert buffer进行合并到真正的索引页的情况发生在如下:
- 辅助索引页被读取到缓冲池中;
- Insert Buffer Bitmap页追踪到该辅助索引页已经没有可用空间;
- Master Thread执行
两次写
double write带给InnoDB存储引擎的是数据页的可靠性。
double write由两部分组成,一部分是内存中的doublewrite buffer,另一部分是物理磁盘上共享表空间中连续128个页,即2个区。两者大小都为2MB。在对缓存池的脏页进行刷新的时候,并不是直接写入到磁盘,而是先将脏页复制到内存中的doublewrite buffer中,之后通过doublewrite buffer分两次,每次1MB顺序的写入共享表空间的物理磁盘上,然后在同步回磁盘,避免了缓冲带来的问题。由于写入是顺序的写入,所以开销不是很大。完成doublewrite后,在将doublewrite buffer中的页写入各个表空间文件中。
自适应哈希索引
哈希是一种非常快的查询方法,时间复杂度O(1)。B+树的查找次数取决于树高,树高多少层,一般需要查询多少次。
InnoDB存储引擎回监控对表上各索引页的查询。如果观察到建立哈希索引能够对性能进行提升,则会建立哈希索引,称之为自适应哈希索引。
异步IO
为了提高磁盘操作性能,当前的数据库系统都采用AIO进行磁盘处理。
刷新临接页
工作原理是:当刷新一个脏页的时候,InnoDB存储引擎会检测该页所在区的所有页,如果是脏页,那么一起刷新。好处是通过AIO可以多个IO写入操作合并成一个IO操作,提高了效率。
1.2版本之后通过参数innodb_flush_neighbors来控制是否启动该特性。