MySQLの浅いエントリと深いエグジットの原則についての簡単な説明

MySQLの浅いエントリと深いエグジットの原則についての簡単な説明

1. ページの概要

MySQL に挿入したデータは最終的にページに保存されます。 InnoDB の設計では、ページは二重にリンクされたリストを介して接続されます。

ページに保存されているデータの行は、単一リンク リストを通じて接続されます。

上図のUser Records領域は、行データを格納するために使用されます。では、なぜ InnoDB はこのように設計されているのでしょうか?ページという概念がないと仮定すると、クエリを実行するときに何千ものデータをすばやくクエリして結果を取得するにはどうすればよいでしょうか?ご存知のとおり、MySQL は優れたパフォーマンスを発揮しますが、ページがなければ、データを 1 つずつ走査するしかありません。

そのページではどのようにしてクイック検索を実現しているのでしょうか?現在のページでは、 User Records内の各レコードを接続する単一のリンク リストをトラバースできます。現在のページでレコードが見つからない場合は、次のページ ポインターを使用してクエリのために次のページにすばやくジャンプできます。

2. 下限と上限

User Recordsを走査しても問題は解決せず、単にデータをグループに分割しただけだと言う人もいるかもしれません。現在のページにデータがまったく存在しない場合でも、前のページのすべてのデータを走査する必要がありますか?これはあまりにも非効率的です。

もちろん、MySQL もこの問題を考慮に入れているため、ページ内には実際にThe Infimum and Supremum Records

Infimum RecordSupremum Recordを使用すると、クエリは特定のページのすべてのUser Records走査する必要がなくなり、これら 2 つのレコードをクエリ対象のターゲット レコードと比較するだけで済みます。たとえば、 id = 101場合、それは明らかに現在のページにはありません。次に、次のページ ポインターを使用して次のページにジャンプして取得できます。

3. ページディレクトリを使用する

すべてのUser Records単一リンク リストではないのかと疑問に思う人もいるかもしれません。探しているデータが現在のページにあることがわかっていても、最悪の場合、探しているデータを見つけるために各ページを 100 回走査する必要があるのではないでしょうか。これを効率的と呼ぶのですか?

これは確かに問題ですが、MySQL ではすでに検討されている問題です。はい、1つずつ走査するのは確かに非常に非効率的です。この問題を解決するために、MySQL はページにPage Directory別の領域を追加します。

名前が示すように、 Page Directory多数のスロットを持つディレクトリであり、各スロットはUser Records内のレコードを指します。ご覧のとおり、数個のデータごとにスロットが作成されます。実際、図に示したデータは設定に厳密に従っています。完全なページには、6 つのデータごとにスロットがあります。

ページ ディレクトリの設計は、別のデータ構造であるスキップ リストを彷彿とさせますが、ここではインデックスの 1 つのレイヤーのみが抽象化されています。

MySQL は、新しいデータが追加されると、対応するスロットを作成します。 Page Directoryを使用すると、ページのデータに対して大まかなバイナリ検索を実行できます。なぜ大まかかというと、結局のところ、 Page Directory完全なデータが含まれていないため、バイナリ検索の結果はおおよその位置しかわかりません。このおおよその位置を見つけた後、 User Recordsに戻って、1つずつトラバースして一致し続ける必要があります。

ただし、この効率は先ほど説明した元のバージョンよりもはるかに高くなります。

4. ページの実際の外観

ページのさまざまなコンポーネントやコンセプトを最初から捨ててしまうと、非常に堅苦しい感じがして、私自身もそれを受け入れることができません。第二に、ページをよく知らない人は、なぜページがこのように設計されているのか理解できない可能性があります。そこで、データのクエリを実行するための一連のアイデアに従って、ページの全体的な外観を紹介しました。

実際、ページには他の領域だけでなく、他の多くのフィールドも保存されていますが、これらはページの理解には影響しません。したがって、ページをより明確に理解した後、実際のページがどのように見えるかを確認できます。

上の図は、ページの実際の構成を示しています。これまでに説明したものに加えて、 File HeaderPage HeaderFree SpaceFile Tailerなど、これまで説明していないものもあります。一つずつ見ていきましょう。

4.1、ファイルヘッダー

実際、 File Headerについては上で説明しましたが、この名前で呼ばれているわけではありません。上で述べた前ページポインターと次ページポインターは、実際にはFile Headerに属しており、それ以外にも多くのデータが存在します。

実際、私は、たくさんのパラメータをリストアップして、そのサイズやその用途を説明することにかなり抵抗を感じています。このページを詳細に理解する必要がある人にとっては、今のところ次の 2 つだけを知っていれば十分です。

  • FIL_PAGE_PREV
  • ページ次へ

これら 2 つの変数は、前述の前のページ ポインターと次のページ ポインターです。これらは、理解しやすいようにポインターと呼ばれていますが、実際にはディスク上のページのオフセットです。

4.2 ページヘッダー

File Headerと比較すると、 Page Headerのデータは私たちにとってより馴染み深いものです。ここでは、内容を詳しくリストするために図を描きました。

これらすべてをここにリストしたのは、これらのパラメータの意味と設定する理由を理解することで、ページの原則と構造をよりよく理解するのに役立つためです。詳細は画像を見れば説明できます。

ここでも文句を言いたいです。ブログの書き方が厳しすぎることが多すぎます。たとえば、パラメータPAGE_HEAP_TOPの場合、多くのブログでは単にHEAPヒープと呼んでいます。これはInitコメントを書いて初期化と呼ぶのと同じです。書かない方がよいでしょう。実際、調べてみると、ここでのヒープは実際にはユーザー レコードを指していることがわかります。

少し混乱するかもしれないパラメータが 2 つあります。 PAGE_N_HEAPPAGE_N_RECSです。どちらも現在のUser Records内のレコード数です。唯一の違いは、 PAGE_N_HEAPは削除対象としてマークされたレコードが含まれるのに対し、 PAGE_N_RECSは実際にクエリできるすべてのデータが含まれることです。

4.3、最小値と最大値の記録

前述のように、 Infimum & Supremum Records現在のページの最大レコードと最小レコードを記録します。実際のところ、それは正確ではありません。より正確な説明は、最小記録と最大記録の開始間隔です。実際には、 Infimum Records現在のページの最小値よりも小さくなり、 Supremum Records現在のページの最大値よりも大きくなります。

4.4 ユーザーレコード

User Records 、結局のところ、私たちのデータが最終的にここに保存されるため、私たちが最も頻繁に接触する部分であると言えます。ページが初期化された後、 User Recordsにはデータは存在しません。システムが稼働し、データが生成されると、 User Recordsのデータは拡大し続け、対応するFree Spaceは徐々に減少します。

User Recordsの概念についてはすでに説明しました。ここでは、私が非常に重要だと思う1つの点、つまり順序​​についてのみお話しします。

クラスター化インデックスでは、キーは実際にはPrimary Keyの順序で配置されていることがわかります。 User Recordsでも同様でしょうか? User Recordsに新しいデータを挿入すると、既存のデータはPrimary Keyの順序に従って並べ替えられますか?

答えは「いいえ」です。これにより、MySQL 処理の効率が低下するためです。

User Records内のデータは、単一のリンク リスト ポインターのポイントによって保証されます。つまり、ディスク上の行データの実際のパフォーマンスは、最初のデータが前にあり、後のデータが後ろにあり、挿入順序に従ってキューに入れられます。 User Records内の行データ間の単一のリンク リストがPrimary Keyに従って配置された順序を形成するだけです。

図で表すと、おおよそ次のようになります。

4.5 空き容量

この部分は、実際には他のモジュールで隠れて説明されています。 最初は、 User Records完全に空です。 新しいデータが入ると、 Free Spaceにスペースが要求されます。 Free Spaceスペースがない場合は、新しいページを要求する必要があることを意味します。 これについては特別なことはありません。

4.6 ページディレクトリ

これは上で説明したこととあまり変わらないので、省略します。

4.7 ファイルトレーラー

これは主に、予期しない極端な状況 (ネットワークの問題、火災、自然災害) により、ディスクにフラッシュするプロセス中にページが失敗し、データの不整合、つまりダーティ ページの形成が発生するのを防ぐためです。

内部にはコンポーネントが 1 つだけあります。

V. 結論

ここまでで、ページについてはすべて説明できたと思います。個人的には、ページの根底にある原則を理解することで、MySQL をより使いやすく合理的に使用し、最高のパフォーマンスを発揮できるようになると考えています。

上記は、MySQL の浅いエントリと深いエグジットの原則の詳細な内容についての簡単な説明です。MySQL ページ原則の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • PHP ページ、MySQL データベースの UTF-8 文字化けコードへの変換、UTF-8 エンコードの問題の概要
  • MySQL でページングに LIMIT を使用する方法
  • MySQL を最適化するために Innodb データ ページ サイズを変更する方法
  • Spring MVC+MyBatis+MySQL でページング機能を実装する例
  • Nodejs mysql ページング方法
  • MySQL の制限使用法とページングクエリステートメントのパフォーマンス分析の詳細な説明
  • PHP+MySQL で簡単なログイン、登録、パスワード変更の Web ページを実装します。
  • MySQL 百万レベルのデータページングクエリ最適化ソリューション
  • MySQL のソートとページング (order by と limit) と既存の落とし穴
  • 数百万のデータボリュームに対する MySQL ページングクエリ方法とその最適化の提案

<<:  Dockerデータを完全にクリーンアップする方法

>>:  CSS 配置レイアウト (位置、配置レイアウト スキル)

推薦する

Docker Compose を使用して nginx のロード バランシングを実装する方法

Dockerネットワーク管理とコンテナIP設定に基づいてNginxロードバランシングを実装するすべて...

Jenkins + Docker + ASP.NET Core の自動デプロイメントの問題について (落とし穴を避ける)

このブログを書くつもりはなかったのですが、実際の操作中に、ネットワークの問題に圧倒されたこと (ネッ...

CSS3を使用してプログレスバー効果を実現し、動的にパーセンテージを追加する

プロジェクト中、プログレスバーを実装するために js の requestAnimationFrame...

Vue.jsは音楽プレーヤーを実装します

この記事では、音楽プレーヤーを実装するためのVue.jsの具体的なコードを参考までに共有します。具体...

MySQL スケジュール バックアップ ソリューション (Linux crontab を使用)

序文この世の愛には値段のつくものもありますが、データには値段のつけられないものがあります。将来、誤っ...

Nginx の負荷分散構成、ダウンタイム発生時の自動切り替えモード

厳密に言えば、nginx には負荷分散バックエンド ノードのヘルス チェック機能はありませんが、デフ...

Ubuntu 18.04 に vsftpd をインストールするための実装コード

vsftpdをインストールする $ sudo apt-get install vsftpd -y v...

CSS を使用してプログレスバーと順序プログレスバーを実装する例

この半月、期末試験の準備にかなりのエネルギーを費やしました。今日はしっかり復習するべきだったのですが...

フローティングメニューを実装するjQueryプラグイン

毎日jQueryプラグインを学ぶ - フローティングメニュー、参考までに、具体的な内容は次のとおりで...

Nginx コンテンツ キャッシュと共通パラメータ設定の詳細

使用シナリオ:プロジェクトのページでは、頻繁に変更されず、個別のカスタマイズも伴わない大量のデータを...

React における ref の一般的な使用法の概要

目次Refsとは何か1. 文字列型参照2. コールバック参照React.createRef() 4....

MySQL の大文字と小文字の区別に関する注意

目次MySQLの大文字と小文字の区別はパラメータによって制御されますMySQLの大文字と小文字の区別...

js で 0ms 遅延タイマーを実装するいくつかの方法

目次キューマイクロタスク非同期/待機メッセージチャネルやっと付録ここ二日間、「タイムリーな setT...

Docker で MySQL マスター スレーブ レプリケーションを実装するためのサンプル コード

目次1. 概要1. 原則2. 実装3. スレーブインスタンスを作成する4. マスタースレーブ構成要約...

JavaScript データ型の詳細な説明

目次1. リテラル1.1 数値リテラル1.2 浮動小数点リテラル1.3 特別な値1.4 文字列リテラ...