插入缓冲
在InnoDB
存储引擎中,主键是行唯一的标识符。通常情况下行记录的插入顺序
是按照主键递增的顺序进行插入的。因此插入聚集索引(Primary Key
)一般是
顺序的,不需要磁盘的随机读取。
但一张表张通常不止一个聚集索引,还有非聚集索引(secondary index
)。
非聚集索引不一定唯一且不一定递增。在进行插入时,数据页的存放还是按主键
进行顺序存放,但是对于非聚集索引叶子节点的插入不再是顺序的了,这时就需要
离散地访问非聚集索引页,由于随机读取的存在而导致插入操作性能下降。
插入缓冲
InnoDB
存储引擎设计了Insert Buffer
,对于非聚集索引的插入或更新操作,不是
每一次直接插入到索引页中,而是先判断插入的非聚集索引页是否在缓冲池中,
若在则直接插入,否则先放入到一个Insert Buffer
对象中,然后以一定的频率和
情况进行Insert Buffer
和辅助索引页子节点的merge
操作,通过将多个插入合并
到一个操作中(在一个索引页中),就大大提高了对非聚集索引插入的性能。
使用 Insert Buffer
的限制
索引是辅助索引(
secondary index
)索引不是唯一的
因此在插入缓冲时,数据库并不去查找索引页来判断插入的记录的唯一性。
如果去查找就又会有离散读取的情况发生了,
Insert Buffer
就失去意义。
-- 通过此命令可查看插入缓冲的信息
SHOW ENGINE INNODB STATUS
seg size
Insert Buffer的问题
在写密集的情况下,插入缓冲会占用过多的缓冲池内存(innodb_buffer_pool
),
默认最大可以占到1/2的缓冲池内存。
Change Buffer
InnoDB
从1.0.x版本开始引入了Change Buffer
,可以视为Insert Buffer
的升级。
InnoDB
存储引擎可以对DML
操作——INSERT
、DELETE
、UPDATE
都进行缓冲,
分别对应:Insert Buffer
、Delete Buffer
、Purge Buffer
。
对一条记录进行更新的操作可能分为两个过程:
- 将记录标记为删除(
Delete Buffer
) - 真正将记录删除(
Purge Buffer
)
InnoDB
提供了innodb_change_buffering
来开启各种Buffer
。默认是all
,启用所有。从
InnoDB
1.2.x版本开始,可以通过参数innodb_change_buffer_max_size
来控制
Change Buffer
最大使用内存的数量。