参考
innodb buffer poll
inser buffer
innodb的索引是B+树,主键索引也叫聚簇索引,是自增的一个非空的键值。所以顺序插入的效率是很高的。但是对于非聚簇索引(第二索引),则往往是离散插入的,效率很低。经常会碰到字符串,或者非递增的数据作为第二索引。
为了减少离散插入造成的效率损失,innodb引入了insert buffer缓冲区,对于第二索引的插入,先放到缓冲区中,然后merge,如果merge的时候,一次可以处理多个,就提升了性能。
insert buffer使用要满足:
- 索引是辅助索引(第二索引)
- 索引不是唯一的
因为唯一索引要判断唯一性,就不能直接放到缓冲区不管。
1 | show engine innodb status; |
segsize表示insert buffer大小:2*16kb
free list代表空闲列表长度
size表示已经合并数据页的长度
change buffer
innodb从1.0.x版本引入change buffer,是insert buffer的加强版,不仅支持insert,还支持其他dml操作(insert buffer, delete buffer, purge buffer)。所以,insert buffer也是个老古董了。
delete操作可能的过程:
- 将记录标记为已删除
- 真正删除记录
第一步就是delete buffer,第二步是purge buffer.
innodb_change_buffering
1 | MySQL [mysql]> show variables like 'innodb_change_buffering'; |
innodb_change_buffering可选的值:
- inserts
- deletes
- purges
- changes
- all
- none
changes = inserts + deletes
all = 所有
none表示不启用
innodb_change_buffer_max_size
1 | MySQL [mysql]> show variables like 'innodb_change_buffer_max_size'; |
innodb_change_buffer_max_size表示change buffer的最大大小,25表示最多使用1/4的缓冲池空间。
change buffer内部也是B+树,具体不研究了。
question
如果binlog=row,需要旧的数据,会影响change buffer吗?
这个mysql实战45讲下面的问题,之前自己也没搞懂,这篇文章写完似乎明白了。
聚簇索引和第二索引都是B+树,不管是新增数据还是删除数据,聚簇索引和第二索引都是要同步的。所以change buffer必要性在这里。同步聚簇索引效率高,同步第二索引效率低,所以先缓存,并不真的落盘同步。等下次查询的时候,在从磁盘读取第二索引的值,将之前的buffer数据读入merge.或者后台线程merge.
然后查老得数据是从聚簇索引查的,不影响。我理解聚簇索引是肯定要持久化到磁盘的,第二索引应该也会持久化到磁盘。所以对于查老得数据,如果内存不存在,直接将磁盘的聚簇索引的记录查出来就是完整的行记录,不用查磁盘的第二索引的值,所以change buffer还是起效果的。