ユーザー テーブルを設計するときに、各人の ID 番号が一意であり、検索する必要があるシナリオを想像してください。ただし、ID番号フィールドは大きいため、主キーとして使用するには適していません。ビジネス コードによって挿入された ID カードが一意であることが保証されている場合、一意のインデックスと通常のインデックスを作成するように選択できます。どのように選択すればよいでしょうか?次に、クエリと更新の実行プロセスを分析します。 クエリプロセス k はテーブル t のインデックスであると仮定します。select 通常のインデックスの場合、k=5 のレコードを見つけた後、5 以外の最初のレコードに遭遇するまで、もう一度検索を続けます。 一意のインデックスの場合、値は一意であるため、見つかったら検索を停止します。 InnoDB はデータ ページ単位で読み取りと書き込みを行うため (データ ページはデフォルトで 16 KB)、データが読み取られるときには、データ ページ全体がまとめてメモリに読み込まれます。 メモリに読み込まれたデータページ内に、k=5 のレコードが含まれている場合、クエリの場合、ユニークインデックスは通常のインデックスよりも検索と判断のプロセスが 1 つ多くなりますが、これは無視できます。 k=5 が現在のデータ ページの最後のエントリである場合、次のデータ ページを読み取る必要があります。しかし、これが起こる可能性は低いので無視できます。 したがって、一般的に、クエリ プロセス中、通常のインデックスと一意のインデックスの間に大きな違いはありません。 バッファを変更する ユニークインデックスと共通インデックスの影響を分析する前に、まず変更バッファ構造を理解しましょう。 変更バッファとは何ですか? 更新操作を実行する際、更新対象のデータ ページがメモリ内にある場合は、直接更新されます。そうでない場合は、データの一貫性に影響を与えることなく、InnoDB は更新操作を変更バッファにキャッシュし、ディスクからデータ ページを読み取るプロセスを排除します。次のクエリ操作で更新が必要なデータ ページが読み取られると、変更バッファー内の更新ステートメントが実行され、データ ページに書き込まれます。ハードディスクに操作を適用するプロセスはマージと呼ばれます。バックグラウンド スレッドは定期的にマージするか、データベースが正常に閉じられるときにもマージ操作が実行されます。 マージの実行プロセスは次のとおりです。
変更バッファは実際にはハードディスクに保存できるデータです。つまり、変更バッファはメモリとハードディスクの両方に存在します。変更バッファは、以前は挿入バッファと呼ばれていました。当初は挿入バッファのみが最適化されていましたが、後に削除と更新のサポートが追加され、名前が変更バッファに変更されました。 最初に更新操作を変更バッファに記録することで、ディスク データ ページをメモリに読み込むプロセスが削減され、ステートメントの実行速度が大幅に向上することがわかります。同時に、メモリへのデータの読み取りはバッファ プール メモリを占有するため、読み取り操作を減らすことでメモリ使用率も向上します。
innodb_change_buffer_max_size を使用して、変更バッファが占有するバッファ プールのサイズを設定できます。 バッファ適用シナリオを変更しますか? 前述のように、変更バッファは更新レコードを事前に保存し、データ ページの読み取りプロセスを削減してパフォーマンスを向上させます。つまり、変更バッファーにさまざまなデータ ページの更新レコードがより多く含まれている場合、メリットは大きくなります。 したがって、書き込みが多く読み取りが少ないビジネス(更新後の即時クエリ)では、変更バッファがより大きな役割を果たします。共通の課金システムやログ記録システムなど。 ビジネスが更新直後にクエリを実行する場合、更新レコードを変更バッファに配置できますが、直後にデータ ページをクエリする必要があるため、マージ プロセスがすぐにトリガーされます。これにより、ランダム アクセス IO の数は減りませんが、変更バッファーのメンテナンス コストが増加し、逆の効果が生じます。 更新プロセス 一意のインデックスの場合、すべての更新操作は一意性制約に違反しているかどうかを判断する必要があります。したがって、必要なデータ ページをメモリに読み込み、変更バッファを使用せずに直接更新する必要があります。したがって、変更バッファは通常のインデックスにのみ役立ちます。 特定の分析を行うには、テーブルに新しいレコードを挿入します。 新しいレコードによって更新されるデータ ページがメモリ内にある場合: 一意のインデックスの場合、適切な位置を見つけ、競合があるかどうかを判断し、値を挿入すると、ステートメントが終了します。 通常のインデックスの場合: 位置を見つけて値を挿入すると、ステートメントが終了します。 したがって、データ ページがメモリ内にある場合、ユニーク インデックスと通常のインデックスの唯一の違いは、判断プロセスです。無視できます。 新しいレコードによって更新されるデータ ページがメモリ内にない場合: 一意のインデックスの場合、データ ページがメモリに読み込まれ、競合が判断され、データが挿入されて、ステートメントが終了します。 共通インデックスの場合、ステートメントは変更バッファに記録され、ステートメントは終了します。 ディスクからメモリへのランダム IO アクセスが関係するため、これはデータベース内で最もコストのかかる操作の 1 つです。通常のインデックスでは、一意のインデックスと比較して読み取り操作が削減されるため、パフォーマンスが大幅に向上します。 ユニークまたは通常のインデックスの選択 クエリと更新の観点から 2 つを比較します。クエリ プロセス中、非常に特殊な状況を除いて、2 つの違いは実際にはそれほど大きくないことがわかっています。 主な違いは、更新中に、更新されるデータ ページがコンテンツ内にない場合です。このとき、ユニークインデックスはユニーク性チェックが必要なため、変更バッファを使用できません。ディスクからコンテンツにデータを読み込むという追加のプロセスがあり、ランダム IO アクセスが伴い、比較的非効率的です。 したがって、ビジネスで良好なパフォーマンスを更新する必要がある場合は、通常のインデックスを選択できます。もちろん、すべてはデータの正確性を確保するという前提に基づいています。 更新の後にクエリが続く場合は、変更バッファをオフにすることを検討してください。その他の場合は、変更バッファによって大幅な改善が得られる可能性があります。
REDOログと変更バッファの比較 InnoDB に REDO ログが導入されたことで、最初にログを書き込み、次に WAL を介してディスクに書き込むことでクラッシュセーフとなり、効率が向上しました。 変更バッファは、ディスクからメモリにデータ ページを読み取るランダム IO プロセスを保存します。 挿入ステートメントを通じて、2 つの関係を分析してみましょう。 mysql> t(id,k) に値 (id1,k1),(id2,k2) を挿入します。 k が通常のインデックスであると仮定すると、k1 によって挿入されたデータ ページはメモリ内にありますが、k2 はメモリ内にありません。 挿入操作を実行する場合、主に次の 4 つの部分が関係します。 InnoDB バッファプール: メモリ領域 再実行ログ: ログ システム表スペース (ibdata1): システム表スペース data(t.idb): データテーブルスペース
実行プロセスは次のとおりです。
この更新ステートメント (挿入、削除、更新操作を含む) の実行コストは、メモリへの書き込みが 2 回、ディスクへの順次書き込みが1 回と非常に低いことがわかります。点線でマークされた操作はバックグラウンド操作であり、応答時間には影響しません。 別のクエリステートメントを見てみましょう。 (k1, k2) 内の k が t から * を選択する 読み取りステートメントが更新ステートメントの直後に実行され、メモリ内のデータがまだそこにあると仮定すると、読み取り操作はシステム テーブルスペースおよび REDO ログとは関係ありません。 実行プロセス:
REDO ログと変更バッファの関係をまとめると次のようになります。 保存場所: 変更バッファもハードディスク上に保存されますが、システム テーブルスペース ibdata1 に保存されます。 REDO ログは別のファイルです。 記録内容: 変更バッファには更新操作の内容が記録され、REDO ログには通常のデータ ページの変更と変更バッファ内の変更が記録されます。 ディスク同期プロセス: メモリ内のデータ ページへの変更の同期は、REDO ログに基づくのではなく、マージ操作によって実行されます。 更新プロセスの観点から見ると、REDO ログはランダム ディスク書き込み IO をシーケンシャル書き込みに変換し、変更バッファはランダム ディスク読み取り IO の消費を節約します。 サーバーの電源が予期せず失われた場合、変更バッファは失われますか? いいえ、変更バッファ内のデータはREDOログに記録されているため、失われることはありません。 変更バッファ データの一部はディスク上にあり、一部はメモリ内にあるためです。ディスク上のデータは結合されているため、失われることはありません。
参考文献 バッファプール 上記は、MySQL のユニーク インデックスと通常のインデックスのどちらを選択すればよいかということです。 MySQL のユニークインデックスと共通インデックスの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
<<: Vue ページをリフレッシュするために provide と injection を適用する
背景要件: ERP システムに「ボタン権限制御」機能を追加する必要があり、権限の制御粒度をボタン レ...
1. CSSファイルの命名規則提案: 文字、_、-、数字を使用します。文字で始まる必要があり、純粋な...
まず、例を見てみましょう。記事テーブルにはタイプフィールドがあり、1 見出し、2 おすすめ、3 ホッ...
Nginx は、ngx_http_limit_req_module モジュールの limit_req...
まず、例を挙げてみましょう(読みたくない場合は、以下の要約だけ読んでください)。 order_typ...
Nginx を使用して Tomcat9 クラスターを構築し、Redis を使用してセッション共有を実...
NetEase Blog で HTML を使用する場合、テンプレートに直接コードを追加できることは...
オリジナルリンク: https://vien.tech/article/138序文私は、マークダウン...
Docker はコンテナを作成するときに、デフォルトでブリッジ ネットワークを使用し、IP アドレス...
SSH は Secure Shell の略で、安全な伝送プロトコルです。Ubuntu クライアントは...
バージョン 0.6 あたりで、Docker に privileged が導入されました。このパラメー...
編集者:この記事では、インタラクティブデザインがブランドコミュニケーションチェーン全体で果たすべき役...
<br />これは、Steven D が書いた Web フロントエンド開発デザインの基本...
目次序文基本的な紹介コードの実装基本構造アップロード分析Excel にエクスポート基本構造Excel...
目次1. ログ関連サービス2. システム内の共通ログファイル1. ログ関連サービスCentOS 6....