ホームページ  >  記事  >  データベース  >  重要な知識ポイントの紹介: InnoDB の挿入バッファー

重要な知識ポイントの紹介: InnoDB の挿入バッファー

coldplay.xixi
coldplay.xixi転載
2020-10-30 17:01:522238ブラウズ

Mysql ビデオ チュートリアル 列では、InnoDB の挿入バッファを紹介します。

重要な知識ポイントの紹介: InnoDB の挿入バッファー

InnoDB エンジンには、パフォーマンスと信頼性の向上をもたらすいくつかの重要な機能があります:

  • Insert Buffer )
  • Double Write
  • アダプティブ ハッシュ インデックス
  • 非同期 IO
  • 隣接ページの更新 (隣接ページのフラッシュ)

今日のトピックは バッファの挿入 (挿入) Buffer) 、InnoDB エンジンの基礎となるデータは構造化された B ツリーに格納されており、インデックスには集約インデックスと非クラスター化インデックスがあるためです。

データを挿入すると、必然的にインデックスが変更されます。言うまでもなく、クラスター化インデックスは通常、昇順になります。非クラスター化インデックスは必ずしもデータではなく、その離散的な性質により、挿入中に構造が継続的に変更され、その結果、挿入パフォーマンスが低下します。

そこで、ノンクラスタード インデックスの挿入パフォーマンスの問題を解決するために、InnoDB エンジンは挿入バッファを作成しました。

挿入バッファのストレージ

重要な知識ポイントの紹介: InnoDB の挿入バッファー

#上の図を見ると、挿入バッファは InnoDB バッファ プールのコンポーネントであると思われるかもしれません。

**重要なポイント: **実際には、これは真か偽です。InnoDB バッファ プールには挿入バッファの情報が含まれていますが、挿入バッファは実際にはデータ ページ (共有テーブル) と同様に物理的に存在します。空間内に B ツリー) の形式で存在します)。

挿入バッファの役割

最初にいくつかの点について説明します。

  • テーブルには 1 つのみを持つことができます。主キー インデックス。これは、その物理ストレージが B ツリーであるためです。 (クラスター化インデックスのリーフ ノードに保存されているデータを忘れないでください。データのコピーは 1 つだけです。)

  • 非クラスター化インデックスのリーフ ノードには、クラスタ化インデックスの主キーが保存されます。クラスター化インデックス

クラスター化インデックスへの挿入

#まず、InnoDB ストレージ内にあることがわかります。エンジンでは、主キーは行の一意の識別子です (つまり、クラスター化インデックスがよく使用されます)。通常、主キーに従ってデータを増分挿入するため、クラスター化インデックスはシーケンシャルであり、ディスクからのランダムな読み取りは必要ありません。

例: テーブル:

CREATE TABLE test(
	id INT AUTO_INCREMENT,
	name VARCHAR(30),
	PRIMARY KEY(id)
);复制代码

上記のように、次の特性を持つ主キー ID を作成しました。

  • ID 列は自動増加します。
  • NULL 値が Id 列に挿入されると、その値は AUTO_INCREMENT によりインクリメントされます。
  • ##同時に、データ ページ内の行レコードは、 id 値
一般に、クラスター化インデックスの順序性により、このタイプの順次挿入は非常に高速であるため、ページ内のデータをランダムに読み取る必要はありません。

ただし、列 ID を UUID などのデータに挿入すると、挿入は非クラスター化インデックスと同じくらいランダムになります。これにより、B ツリー構造が変化し続けることになり、必然的にパフォーマンスに影響が出ます。

非クラスター化インデックスの挿入

多くの場合、テーブルには多数の非クラスター化インデックスが含まれます。たとえば、b フィールドに従ってクエリを実行し、bフィールドが一意ではありません。次の表に示すように:

CREATE TABLE test(
	id INT AUTO_INCREMENT,
	name VARCHAR(30),
	PRIMARY KEY(id),
	KEY(name)
);复制代码
ここでは、次の特性を持つ x テーブルを作成しました:

    クラスタード インデックス ID
  • があります。一意ではない非クラスター化インデックスがあります。インデックス名
  • データを挿入するとき、データ ページは主キー ID に従って順番に格納されます。
  • 補助インデックス名のデータ挿入は次のとおりです。シーケンシャルではありません
非クラスター化インデックスも同様です。B ツリーですが、リーフ ノードにはクラスター化インデックスの主キーと名前の値が格納されます。

name 列のデータがシーケンシャルであるという保証はないため、非クラスター化インデックス ツリーの挿入はシーケンシャルであってはなりません。

もちろん、名前列が時間型データを挿入する場合、非クラスター化インデックスの挿入も順次に行われます。

挿入バッファの登場

ノンクラスタード インデックス挿入の離散的な性質が挿入パフォーマンスの低下につながることがわかります。そのため、InnoDB エンジンは挿入バッファーを使用して挿入パフォーマンスを向上させます。

挿入バッファを使用して挿入する方法を見てみましょう:

重要な知識ポイントの紹介: InnoDB の挿入バッファー

まず、非挿入または更新操作についてです。 -クラスター化インデックス。毎回インデックス ページに直接挿入するのではなく、挿入された非クラスター化インデックス ページがバッファー プール内にあるかどうかを最初に判断します。

存在する場合は直接挿入し、存在しない場合は、まず Insert Buffer オブジェクトに挿入します。

外見上は、ツリーが非クラスター化インデックスのリーフ ノードを挿入したように見えますが、実際には、それらは別の場所に格納されています。

次のコマンドを使用して、バッファーおよび補助インデックス ページの挿入を実行します。特定の頻度と状況 子ノードのマージ操作では、通常、複数の挿入操作がマージされ、非クラスター化インデックスの挿入パフォーマンスが大幅に向上します。

Insert Buffer的使用要求

  • 索引是非聚集索引
  • 索引不是唯一(unique)的

只有满足上面两个必要条件时,InnoDB存储引擎才会使用Insert Buffer来提高插入性能。

那为什么必须满足上面两个条件呢?

第一点索引是非聚集索引就不用说了,人家聚集索引本来就是顺序的也不需要你

第二点必须不是唯一(unique)的,因为在写入Insert Buffer时,数据库并不会去判断插入记录的唯一性。如果再去查找肯定又是离散读取的情况了,这样InsertBuffer就失去了意义。

Insert Buffer信息查看

我们可以使用命令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的好处,但目前Insert Buffer也存在一个问题:

即在写密集的情况下,插入缓冲会占用过多的缓冲池内存(innodb_buffer_pool),默认最大可以占用到1/2的缓冲池内存。

占用了过大的缓冲池必然会对其他缓冲池操作带来影响

Insert Buffer的优化

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 Bitmap页追踪到该辅助索引页已无可用空间时
  • Master Thread线程中每秒或每10秒会进行一次Merge Insert Buffer的操作

一句话概括下:

Insert Buffer 就是用于提升非聚集索引页的插入性能的,其数据结构类似于数据页的一个B+树,物理存储在共享表空间ibdata1中 。

相关免费学习推荐:mysql视频教程

以上が重要な知識ポイントの紹介: InnoDB の挿入バッファーの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.imで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。