InnoDB 엔진에는 더 나은 성능과 안정성을 제공하는 몇 가지 주요 기능이 있습니다.
오늘의 주제는插入缓冲(Insert Buffer)
입니다. InnoDB 엔진의 기본 데이터 저장 구조는 B+ 트리이고 인덱스의 경우 클러스터형 인덱스와 비클러스터형 인덱스가 있기 때문입니다.
데이터를 삽입하면 필연적으로 인덱스가 변경됩니다. 말할 필요도 없이 클러스터형 인덱스는 일반적으로 오름차순입니다. 비클러스터형 인덱스는 반드시 데이터일 필요는 없으며, 이산적 특성으로 인해 삽입 중에 구조가 지속적으로 변경되어 삽입 성능이 저하됩니다.
그래서 비클러스터형 인덱스 삽입 성능 문제를 해결하기 위해 InnoDB 엔진에서는 Insert Buffer를 만들었습니다.
위 그림을 보면 Insert Buffer가 InnoDB 버퍼 풀의 구성 요소라고 생각하실 수 있습니다.
**요점: **실제로는 true 또는 false입니다. InnoDB 버퍼 풀에는 Insert Buffer의 정보가 포함되어 있지만 실제로 Insert Buffer는 데이터 페이지와 마찬가지로 물리적으로 존재합니다. B+ 트리의 형태).
먼저 몇 가지 사항에 대해 이야기해 보겠습니다.
테이블은 기본 키 인덱스를 하나만 가질 수 있습니다. 이는 물리적 저장소가 B+ 트리이기 때문입니다. (클러스터형 인덱스 리프 노드에 저장된 데이터는 단 하나의 데이터 복사본임을 잊지 마세요)
비클러스터형 인덱스 리프 노드는 클러스터형 인덱스의 기본 키를 저장합니다
먼저 우리는 InnoDB 스토리지 엔진에서 기본 키가 행의 고유 식별자(즉, 우리가 자주 이야기하는 클러스터형 인덱스)라는 것을 알고 있습니다. 일반적으로 기본 키에 따라 데이터를 증분식으로 삽입하므로 클러스터형 인덱스는 순차적이며 디스크에서 무작위로 읽을 필요가 없습니다.
예를 들어 테이블:
CREATE TABLE test( id INT AUTO_INCREMENT, name VARCHAR(30), PRIMARY KEY(id) );复制代码
위와 같이 기본 키 ID를 생성했는데 다음과 같은 특징이 있습니다.
일반적으로 클러스터형 인덱스의 질서로 인해 무작위로 저장할 필요는 없습니다. 이러한 유형의 순차적 삽입은 매우 빠르기 때문에 페이지의 데이터를 읽습니다.
하지만 UUID와 같은 데이터에 열 ID를 삽입하면 비클러스터형 인덱스만큼 무작위로 삽입됩니다. 이로 인해 B+ 트리 구조가 계속 변경되고 성능이 필연적으로 영향을 받게 됩니다.
우리 테이블에는 여러 개의 비클러스터형 인덱스가 있을 때가 많습니다. 예를 들어 b 필드에 따라 쿼리했는데 b 필드가 고유하지 않습니다. 다음 표와 같이
CREATE TABLE test( id INT AUTO_INCREMENT, name VARCHAR(30), PRIMARY KEY(id), KEY(name) );复制代码
여기서 순차 저장소를 만들었습니다
Insert Buffer의 등장
비클러스터형 인덱스 삽입의 이산적 특성으로 인해 삽입 성능이 저하되는 것을 볼 수 있으므로 InnoDB 엔진은 삽입 성능을 향상시키기 위해 Insert Buffer를 설계했습니다.먼저 Non-Clustered Index의 삽입이나 업데이트 작업을 위해 매번 인덱스 페이지에 직접 삽입하는 대신 먼저 insert non-clustered 인덱스 페이지가 버퍼 풀에 있는지 여부입니다. 있을 경우 직접 삽입하고, 없으면 먼저 Insert Buffer 개체에 넣으십시오.
외적으로는 트리가 비클러스터형 인덱스의 리프 노드를 삽입한 것처럼 보이지만 실제로는 다른 위치에 저장되어 있습니다.
삽입 버퍼와 보조 노드의 병합 작업을 수행합니다. 특정 빈도와 상황의 인덱스 페이지는 일반적으로 여러 삽입 작업이 함께 병합되어 비클러스터형 인덱스의 삽입 성능을 크게 향상시킵니다.只有满足上面两个必要条件时,InnoDB存储引擎才会使用Insert Buffer来提高插入性能。
那为什么必须满足上面两个条件呢?
第一点索引是非聚集索引就不用说了,人家聚集索引本来就是顺序的也不需要你
第二点必须不是唯一(unique)的,因为在写入Insert Buffer时,数据库并不会去判断插入记录的唯一性。如果再去查找肯定又是离散读取的情况了,这样InsertBuffer就失去了意义。
我们可以使用命令SHOW ENGINE INNODB STATUS来查看Insert Buffer的信息:
------------------------------------- INSERT BUFFER AND ADAPTIVE HASH INDEX ------------------------------------- Ibuf: size 7545, free list len 3790, seg size 11336, 8075308 inserts,7540969 merged sec, 2246304 merges ...复制代码
使用命令后,我们会看到很多信息,这里我们只看下INSERT BUFFER 的:
seg size 代表当前Insert Buffer的大小 11336*16KB
free listlen 代表了空闲列表的长度
size 代表了已经合并记录页的数量
Inserts 代表了插入的记录数
merged recs 代表了合并的插入记录数量
merges 代表合并的次数,也就是实际读取页的次数
merges:merged recs大约为1∶3,代表了Insert Buffer 将对于非聚集索引页的离散IO逻辑请求大约降低了2/3
说了这么多针对于Insert Buffer的好处,但目前Insert Buffer也存在一个问题:
即在写密集的情况下,插入缓冲会占用过多的缓冲池内存(innodb_buffer_pool),默认最大可以占用到1/2的缓冲池内存。
占用了过大的缓冲池必然会对其他缓冲池操作带来影响
MySQL5.5之前的版本中其实都叫做Insert Buffer,之后优化为 Change Buffer
可以看做是 Insert Buffer 的升级版。
插入缓冲( Insert Buffer)这个其实只针对 INSERT 操作做了缓冲,而Change Buffer 对INSERT、DELETE、UPDATE都进行了缓冲,所以可以统称为写缓冲,其可以分为:
Insert Buffer
Delete Buffer
Purgebuffer
Insert Buffer到底是个什么?
其实Insert Buffer的数据结构就是一棵B+树。
在MySQL 4.1之前的版本中每张表有一棵Insert Buffer B+树
目前版本是全局只有一棵Insert Buffer B+树,负责对所有的表的辅助索引进行Insert Buffer
这棵B+树存放在共享表空间ibdata1中
以下几种情况下 Insert Buffer会写入真正非聚集索引,也就是所说的Merge Insert Buffer
一句话概括下:
Insert Buffer 就是用于提升非聚集索引页的插入性能的,其数据结构类似于数据页的一个B+树,物理存储在共享表空间ibdata1中 。
相关免费学习推荐:mysql视频教程
위 내용은 중요한 지식 포인트 소개: InnoDB의 삽입 버퍼의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!