前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >change buffer,你了解么?

change buffer,你了解么?

作者头像
AsiaYe
发布2020-05-06 23:23:08
2.1K0
发布2020-05-06 23:23:08
举报
文章被收录于专栏:DBA随笔

//

change buffer,你了解么?

//

最近在极客时间看丁奇大佬的《MySQL45讲》,真心觉得讲的不错,把其中获得的一些MySQL方向的经验整理整理分享给大家,有兴趣同学可以购买相关课程进行学习。

今天分享的内容是普通索引和唯一索引的区别,期间会印出来change buffer的内容。

01

普通索引和唯一索引

普通索引和唯一索引的概念相比大家都不陌生,这里我们先来说说这两种索引在查询和更新上的差别,先说查询。

1、查询上的差别:

假设我们在字段k上建立索引,对于select * from table where k=1;这个SQL语句,普通索引和唯一索引的执行过程如下:

对于普通索引,当我们找到k=1的记录之后,首先需要通过索引上的id字段"回表"查询聚集索引上其他字段的内容,然后要接着向后寻找其他k=1的值,重复这个过程。因为普通索引可能有重复的现象发生。

对于唯一索引,查找到第一个满足条件的记录后,查找的过程就会停止。

严格来说,唯一索引的搜索过程比较快,因为"回表"的数据记录少,但是在实际操作中,这两种索引的带来的消耗几乎相等,差别微乎其微

2、更新上的差别:

普通索引的更新,会使用到change buffer;

唯一索引的更新,不会使用到change buffer;

那么什么是change buffer?

02

change buffer介绍

这里我们需要引入change buffer的概念。

change buffer是内存中的一块区域,它保存在Innodb的buffer pool中,它在磁盘上也有对应的持久化空间,在系统表空间ibdata中。MySQL中的change buffer信息如下,默认值是25,代表它的大小最大只能占用到innodb buffer pool的25%大小,如下:

代码语言:javascript
复制
mysql> show variables like "%change%";
+-------------------------------+-------+
| Variable_name                 | Value |
+-------------------------------+-------+
| innodb_change_buffer_max_size | 25    |
| innodb_change_buffering       | all   |
| session_track_state_change    | OFF   |
+-------------------------------+-------+
3 rows in set, 1 warning (0.01 sec)

当我们需要更新一条数据记录的时候,如果这个记录所在的数据页A在内存中,那么直接更新内存中的数据页A即可,如果数据页B不在内存中,这个时候,Innodb会将这些更新操作缓存在change buffer中,当下次需要访问磁盘上的数据页B时,将数据页B从磁盘上加载到内存里面,然后应用change buffer中与这个数据页有关的操作。通过这种方式,有两个好处:

第一、将原本2次的磁盘访问,整合成1次磁盘访问,并且能够保证数据的一致性。

第二、数据页B读入内存是需要占用内存空间的,这种方式能够避免内存的使用,提高内存的利用率

应用change buffer中与该数据页相关的操作的这个过程,我们称之为数据页的merge操作,merge操作在以下的场景下会触发:

1、访问数据页的时候

2、后台线程每秒都会merge

3、数据库正常关闭的情况下

为什么唯一索引不能使用change buffer?

上面说普通索引和唯一索引在更新上的区别的时候,我们说了,普通索引可以使用change buffer,而唯一索引不能使用change buffer,原因是唯一索引在做insert或者update的时候,需要判断索引记录的唯一性,而判断唯一性必须要在内存中判断,所以数据页会被加载到内存中,如果数据页已经加载到了内存中,那么当然是直接更新内存更快了。

03

唯一索引和普通索引在更新时候的差异

上面我们说过,更新的时候,唯一索引不能使用change buffer而普通索引能够使用change buffer.

这里我们详细看看在更新记录的时候,这俩分别干了什么事情。以update table where k=4举例子:

1、当要更新的记录在内存中的时候。

普通索引k会找到索引记录等于3和5的位置,然后在中间插入k=4的记录;

唯一索引k会找到索引记录等于3和5的位置,然后判断没有冲突,插入k=4的记录;

可以看出,当记录在内存中的时候,这俩差别不大,仅仅是唯一索引多了一步判断唯一性的操作。这个判断,仅仅会消耗很小一部分cpu的资源。

2、当要更新的记录不在内存中的时候。

唯一索引需要将数据页加载到内存中,判断这个值没有冲突,然后插入这个新值;

普通索引则是将更新记录在change buffer,语句执行就结束了。

可以看到,普通索引利用了change buffer,减少了磁盘上的随机访问,对性能的提升比较明显。

04

change buffer使用场景

在一些写多读少的业务中,change buffer能够发挥很好的作用。它可以将多次对磁盘的操作,合并成一次merge操作,从而提高MySQL的性能,一次性merge的操作越多,收益就越大。

但是需要注意,如果你的数据写入之后。立马会读取(也就意味着需要从磁盘读取到内存),那么建议不要使用change buffer,因为在这种情况下,使用change buffer不会减低IO次数,反而多了change buffer的维护开销。

05

change buffer和redo log的交互

下面的示意图表示了change buffer和redo log的合作过程。

当我们要更新一条普通索引记录的时候:

1、如果这条记录在内存中,那么直接更新内存;

2、如果该记录没有在内存中,那么就需要更新change buffer

3、更新完change buffer之后,MySQL会在redo log中记录下change buffer的修改,

4、事务就算完成了,后续binlog落盘,redo log commit

5、当需要读取不在内存中的记录时,会将该数据页从磁盘加载到内存,然后应用change buffer中的修改,也就是merge操作

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DBA随笔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档