MYSQL の基礎となる原則を理解するのに役立つ記事
mysql ビデオ チュートリアル コラムでは、基礎となる原則を紹介します。
- (各ストレージ エンジン Mysql ストレージ エンジンの公式ドキュメントの説明は次のとおりです)
プロセスは同じですが、まずこのデータを見つけてから更新する必要があります。 UPDATE
プロセスを理解するために、まず Innodb のアーキテクチャ モデルを見てみましょう。 Innodb アーキテクチャ
最後の MYSQL 公式 InnoDB アーキテクチャ図:
内部モジュール
コネクタ (JDBC、ODBC、など) =>
[MYSQL Internal
[Connection Pool] (授权、线程复用、连接限制、内存检测等) => [SQL Interface] (DML、DDL、Views等) [Parser] (Query Translation、Object privilege) [Optimizer] (Access Paths、 统计分析) [Caches & Buffers] => [Pluggable Storage Engines]复制代码
]
=> [ファイル]
メモリ構造
データをクエリするときは、まず現在クエリしている
page を取得し、バッファ プール
に移動して、現在のページ
は バッファ プール
にあります。ある場合は、直接入手してください。 そして、
の場合、Buffer
の値が直接変更されます。現時点では、バッファ プール
内のデータは実際にディスクに保存されているデータと矛盾しており、
ダーティ ページと呼ばれます。時々、Innodb ストレージ エンジンは
ダーティ ページ データ をディスクにフラッシュします。一般に、データを更新するときは、変更のためにデータを
バッファ に読み取り、それをディスクに書き戻して
disk IO 操作を完了する必要があります。
update
アーキテクチャのバッファプールに領域があることがわかります。ダイアグラムの名前:
バッファを変更。名前が示すように、
は変更されたデータ用のバッファを作成するために使用されます。一意のインデックス
を持たずにデータを更新する場合、変更されたデータは change バッファ
に直接配置されます。その後、merge
操作を通じて更新が完了するため、その ディスク ドロップに対する IO
操作が削減されます。 上で述べたことには条件があります:
一意のインデックスのないデータが更新されるとき
- 一意のインデックスのないデータが更新されるとき
- 直接配置できます
changebuffer
と入力してみてはいかがでしょうか?一意制約
のあるフィールドの場合、データを更新すると、更新されたデータが既存のデータと重複する可能性があるため、ディスクからすべてのデータを読み取って比較することしかできません
一意性を判断するため。したがって、データの書き込みが
多くなり、読み取りが少なくなる
場合、 innodb_change_buffer_max_size - の割合を増やすことで、
の
changebufferを調整できます。バッファ プール
、デフォルトは 25 (つまり 25%)です。マージがどのように機能するかという質問がまた出てきます。
状況は 4 つあります。
他のアクセスがある場合、現在のページのデータはディスクにマージされますバックグラウンド スレッドのスケジュールされたマージ
- システムが正常にシャットダウンする前に、一度マージします
- redo ログ
- いっぱいになったら、ディスクにマージします
1. redo ログとは
redo について話すとき、innodb について話さなければなりません
、WAL メソッドを使用します (ログの書き込み、書き込み前にログを記録します)
この方法では、データベースがクラッシュしたときに、redo から直接ログにデータを復元します
データの正確性を確保するため、
REDO ログはデフォルトで 2 つのファイルに保存されますib_logfile0
、両方のファイルは固定サイズ
です。なぜ固定サイズが必要なのでしょうか? これは、
redo ログ
の
機能が原因で発生します。この機能は、継続的なストレージ スペースである必要があります 2. ランダムな読み取りと書き込み、およびシーケンシャルな読み取りと書き込み
画像を見てください
メカニカル ハードディスクの読み取りと書き込みのシーケンスは次のとおりです。
- 読み取りと書き込みの開始
- ソリッド ステートの読み取りと書き込み:
-
- フラッシュ メモリ チップを直接見つけます (これが、ソリッドステートが機械式よりも高速である理由です)
- 読み取りと書き込みを開始します
実際には、機械式かどうかに関係なく、ソリッドステートの場合、ストアに行くとき、それらはすべて
ファイル システム
を通じてディスクを処理します。それらを処理する方法は 2 つあります。ランダム読み取りおよび書き込み
およびシーケンシャル読み取りおよび書き込み
- ランダム読み取りおよび書き込みで保存されたデータは、異なる
ブロックに分散されます
(デフォルトは 1 ブロック = 8 セクター = 4K) - シーケンシャル ストレージに関しては、名前が示すように、データが
一連の連続したブロック
に分散されるため、読み取り速度が大幅に向上します
3. アーキテクチャ図に戻ります
バッファ プール
のログ バッファ
を参照してください。 REDO ログの前に存在していたバッファを書き込むために使用されます。ここでは、REDO ログの具体的な実行戦略が 3 つあります。
-
Log Buffer
を書き込む必要はありません。 1 秒ごとに書き込むだけで済みます。REDO はディスク データを 1 回だけログに記録するため、高いパフォーマンスを発揮しますが、1 秒以内にデータの一貫性の問題が発生します。強いリアルタイム パフォーマンス
、弱い一貫性
に適用されます。たとえば、コメント領域のコメント
- 書き込み
ログ バッファ
と同時にディスクに書き込みます。パフォーマンスは最悪ですが、一貫性は最高です。弱いリアルタイム
、強い一貫性
に適用可能(支払いシナリオ
- write
ログバッファ
、書き込みなど)os バッファ
に転送します (毎秒fsync
を呼び出してデータをディスクにフラッシュします)。優れたパフォーマンスと高いセキュリティを備えています。これは、中程度のリアルタイム
中程度の一貫性
(注文タイプ
など)です。
実行ポリシーは、
innodb_flush_log_at_trx_commit
を通じて設定できます。デフォルトは1
メモリ構造の概要
- ##バッファ プールは読み取りを高速化するために使用されます
- 変更バッファは、非一意のインデックスを使用せずに書き込みを高速化するために使用されます
- ログ バッファは、REDO ログの書き込みを高速化するために使用されます
- アダプティブ ハッシュ インデックス
主にクエリを高速化するために使用されます
ページ。クエリを実行するとき、Innodb はインデックス検索メカニズムを監視することによって、現在のクエリが
ハッシュ インデックスを通過できるかどうかを判断します。たとえば、LIKE 演算子と % ワイルドカード文字は使用できません。
#ハードディスク構造
1. システム テーブルスペース
は、
ibdata1というファイルに保存され、次の内容が含まれます。
Doublewrite Buffer#InnoDB データ ディクショナリは、テーブル構造情報、インデックスなどのメタデータを保存します。
- バッファ プール
- がデータ ページを書き込むとき、データ ページはファイルに直接書き込まれません。代わりに、最初にこの領域に書き込まれます。この利点は、オペレーティング システム、ファイル システム、または mysql がハングしたときに、この Buffer
- からデータを直接取得できることです。
変更バッファ Mysql がシャットダウンすると、変更はディスクに保存されます
Undo ログはトランザクション変更操作を記録します
- 2. テーブルごとのファイル テーブルスペース
- 各テーブルには、データとインデックスを保存するファイル
があります。
を使用すると、file-per-table tablespace
- ALTER TABLE
- および
TRUNCATE TABLE
のパフォーマンスを大幅に向上できます。たとえば、ALTER TABLE
では、共有テーブル スペースに存在するテーブルと比較して、テーブルを変更するときにテーブル コピー操作
が実行され、テーブル スペースの数が増加する可能性があります。占有ディスク容量
。このような操作では、テーブル内のデータとインデックスと同じくらいの追加スペースが必要になる場合があります。この領域は、file-per-table tablespace
のようにオペレーティング システムに解放されません。File-per-table テーブルスペース データ ファイルは、I/O の最適化、スペース管理、またはバックアップのために別のストレージ デバイス上に作成できます。これは、テーブルのデータと構造を異なるデータベース間で簡単に移行できることを意味します。
データ破損が発生した場合、バックアップやバイナリ ログが利用できない場合、または MySQL サーバー インスタンスを再起動できない場合、テーブルを単一のテーブルスペース データ ファイルに保存すると時間が節約され、リカバリが成功する可能性が高まります。
- もちろん、利点と欠点があります:
-
- ストレージスペースの使用率が低いため、断片化が発生し、
テーブルを削除するときにパフォーマンスに影響します
(断片化を自分で管理しない場合) - 各テーブルが分割されているためそれぞれのテーブル ファイルにデータを書き込むと、オペレーティング システムは
fsync
ファイルへのデータの 1 回限りのフラッシュを実行できません。 - mysqld は各テーブル ファイルの
ファイル ハンドル
を維持し続けます。ファイルへの継続的なアクセスを提供します
3. 一般テーブルスペース
- 一般テーブルスペースは
共有テーブルスペース
とも呼ばれ、データを保存できます。複数のテーブルから
- 同じ数のテーブルを保存する場合、消費されるストレージは
テーブルあたりのテーブル領域
- より小さくなります。 MySQL 通常のテーブルスペースにテーブル パーティションを配置するためのサポートは 5.7.24 で非推奨となり、将来の MySQL バージョンではサポートされなくなります。
4. 一時テーブルスペース
は、
ibtmp1
というファイルに保存されます。通常の状況では、Mysql は起動時に一時テーブルスペースを作成し、停止時に一時テーブルスペースを削除します。そしてそれは自動的に拡張することができます。5. 元に戻すテーブルスペース
- 変更操作の
原子性
を提供します。つまり、変更の途中で例外が発生した場合、それをロールバックできます。元に戻すログを介して。 - トランザクションとこの変更操作の開始前の元のデータが保存されます。
- アーキテクチャに示すように、UNDO ログはロールバック セグメント (ロールバック セグメント) に存在し、ロールバック セグメントは
システム表スペース「UNDO 表スペース」一時表スペース
に存在します。ダイアグラム。
Redo Log
前述のとおり、
要約すると、更新 SQL ステートメントを実行すると何が起こるかについてです。
- お問い合わせください。変更されるデータの一部 (ここでは
origin
と呼びます) は、実行プログラム - に返されます。実行プログラムでは、データの変更は
modification
と呼ばれます。 -
変更
をメモリにフラッシュし、#バッファプールのバッファを変更します
エンジン層: アンドゥログを記録します(トランザクションのアトミック性を達成するため) - エンジン レイヤー: REDO ログを記録 (クラッシュ リカバリに使用)
- サービス レイヤー: bin ログを記録 (DDL を記録)
- 更新成功結果を返す
- データ待機中 ワーカー スレッドによってディスクにフラッシュされました
Bin log はUndo
このログは、
Redo## と言いました# ちなみにBin ログ
.- innodb
- エンジンとはほとんど関係がありません。前述の 2 つのログはどちらも innodb エンジンです。層。そして、
Bin log
はサービス層
にあります。そのため、さまざまなエンジンで使用できます。その主な機能は何ですか?まず、
Bin log - は、各
DDL DML
ステートメントをイベントの形式で記録するもので、論理的な意味でのログです。 マスター/スレーブ レプリケーション - を実現できます。
サーバーから
main
サーバーのbin log
ログを取得します。を選択して実行します。データリカバリ
を行い、一定期間のログを取得し、再度実行してください。 -
SQL ステートメントに従ってグローバル プレビューを完了したら、SQL を振り返ってリッチにしてみましょう。
index
## を追加しましょう # ゴージャスな分割線
##InnoDB のインデックス#インデックス記事
が何であるかを完全に理解したい場合は、その
ファイル ストレージ レベルを理解する必要があります
Innodb はファイル ストレージを 4 つのレベルに分割しますページ、エクステント、セグメント、テーブルスペース
それらの関係は次のとおりです:
エクステント
サイズは1M
64、つまり
- 16KB
です。通常、ファイル システムで参照されるページ サイズは
4KBで、
512Byteの
8セクターが含まれています。
ストレージ構造 B ツリー バリアント B ツリー
では、なぜ主キーを順序付けする必要があるのかを尋ねられることがあります。順序付きフィールドでインデックスを作成し、データを挿入します。
保存する際、innodb は
に 1 つずつ順番に保存し、1 ページがいっぱいになると新しいページに適用して保存を続けます。
ただし、フィールドが順序付けされていない場合、保存場所は別のページになります。データが
であるfull
ページ
が発生し、に保存されると、
ページ分割フラグメント
が形成されます。
いくつかの異なるインデックス構成形式
- 上の
B ツリー
図に示すように、クラスター化インデックスでは、行のデータ
が子ノードに保存されます。 , そして、インデックスの 並び順
とインデックスのキー値の順序が一致していれば、
クラスター化インデックスになります。主キー インデックスはクラスター化インデックスです。主キー インデックスを除き、その他はすべて
補助インデックス 補助インデックスです。 - 補助インデックス
を作成すると、そのインデックスはリーフノード
自身の値と
主キーインデックスの値のみが保存されます。これは、補助インデックスを通じてすべてのデータをクエリする場合、まず
補助インデックスで
主キー値を見つけてから、
主キー インデックス#に移動することを意味します。 ## 内部で、関連するdata
が見つかりました。このプロセスはテーブルに戻る
rowid - と呼ばれます。
主キー インデックス
がない場合はどうすればよいですか?主キーはありませんが、一意のキーがあり、それが null ではない場合、このキーに基づいて
- クラスター化インデックス
- が作成されます。
上記のいずれも持っていない場合でも、心配する必要はありません。innodb は
rowid - と呼ばれるものを維持し、この id
# に基づいて
クラスター化インデックスを作成します。
- が作成されます。
- full table query
- を実行します)。たとえば、性別フィールドです。これにより、多くの保管スペースが無駄になります。
ジョイント フィールド インデックス ( idx(name, class_name) など) -
select * from stu where class_name の実行時= xx および name = lzw- をクエリする場合、オプティマイザは SQL を
- name = lzw および class_name = xx
# に最適化するため、インデックス
idxを使用することもできます。
#select ··· where name = lzw が必要な場合は、別の - name
インデックスを作成する必要はなく、
idxに直接移動します。インデックス
カバーインデックス
。今回クエリする - すべてのデータ
がインデックスに含まれている場合、クエリのために
テーブルに戻る必要はありません。例:select class_name from stu where name =lzw
インデックス条件プッシュダウン (index_condition_pushdown)
- name = lzw および class_name = xx
- このようなものがあります。記事 SQL、
select * from stu where name = lzw and class_name like '%xx'
-
インデックス条件がない場合は、
を押します。 like ' %xx' - クエリ条件が続くため、ここではまず
name
に基づいてidx ジョイント インデックス
に移動します。いくつかのデータをクエリした後、テーブル
クエリ全行データ
に戻り、サーバー層
でフィルタリングと同様に実行してデータを検索しますこれは、
サーバー層
のフィルタリング操作 をエンジン層 - にプッシュすることと同じです。図に示すように:
-
離散性の高いフィールドを追加してインデックスを作成できます。
結合インデックスは離散性が高いことを優先します (最初のフィールドに基づいて最初に照合されるため、迅速に検索できます)
- 頻繁に更新されるフィールドにはインデックスを作成できません (
- ページ分割が発生します 、インデックスは順番に保存されます。ストレージ ページがいっぱいの場合、再度挿入するとページ分割が発生します)
- replace、sum、count などの
- 関数を使用する場合、インデックスは使用されないため、追加の関数を構築する必要はありません。 int への文字列変換などの処理が発生し、
- 特に長いフィールドにインデックスを付ける必要はありません。最初の数ビットをインターセプトしてインデックスを作成できます (
select count(distinct left( name, 10))/count(*)
へ 分散の程度を見て、上位のいくつかを抽出することを決定します) -
ヒント: SQL を実行するとき、次のことができます。インデックスを使用できるかどうかを正確に言うことはできません。結局のところ、それはすべてオプティマイザーです。決定した
。たとえば、 - Cost Base Optimizer コストベースのオプティマイザーを使用する場合は、コストが最も低い最適化を使用します。
-
インデックスを理解した後、ロックの章のコピーを開くことができます。
-
ロックの章
4 つの主要な機能
まず、よく知られているいくつかの基本概念を確認してみましょう:
- 原子性 (Undo ログによって実装)
- 一貫性
- 分離
- 永続性 (クラッシュ リカバリ、REDO ログの二重書き込み)
読み取り一貫性の問題は、データベースのトランザクション分離レベル (SQL92 標準) によって解決する必要があります。
トランザクション内の前提条件:
- ダーティ リード (データが読み取られていない)まだ他の人によってコミットされ、その後他の人がそれをロールバックします)
- 反復不可能な読み取り (データが初めて読み取られ、その後、他の誰かがコミットを変更し、再度読み取り、データを読み取ります)データ)
- ファントム読み取り (範囲クエリ中に他の人が新たに追加したデータを読み取る)
SQL92 標準規則: (同時実行性は左から右に減少します)
- #ヒント: Innodb では、Repeatable Read のファントム読み取りはそれ自体で解決されるため、存在できません
Innodb のRepeatable Read (RR) でのファントム読み取りの問題を解決する方法
Lock Model
- LBCC (Lock Based Concurrency Control) 読み取り前にロックを追加するただし、これによりパフォーマンスの問題が発生する可能性があります => 読み取り中にロックすると、他のトランザクションの読み取りと書き込みができなくなり、パフォーマンスが低下します
- MVCC (Multi Version Concurrency Control) スナップショットの読み取り時に現在時刻を記録し、他のユーザーは読み取りだけを行うことができますスナップショット => パフォーマンス消費、ストレージ消費
これら 2 つのソリューションは Innodb で一緒に使用されます。
RR
の MVCC 実装について簡単に説明します。図中のロールバック ID の初期値は 0 ではなく NULL にする必要があります。便宜上、0# と記述します。
- ##RC の MVCC 実装は、同じトランザクションの複数の読み取りのバージョンを作成します。
一方、
RR は、同じトランザクションのいずれか 1 つのバージョンを作成します
MVCC
InnoDB ロックと
LBCCを組み合わせることにより、InnoDB は、
ロックなし条件下でのファントム読み取りの問題を解決できます。
Serializableの代わりに、トランザクションは
同時実行なしで
シリアル化される必要があります。
がどのように実装されるかを詳しく見てみましょう
RR
トランザクション分離レベルロック Innodb での MVCC の詳細な実装
1. Innodb のロック
共有ロックと排他ロック共有ロックと排他ロック=> (S, X)- インテンション ロックインテンション ロック=> これは何ですか「2 つのロックがあり、実際には テーブル レベル
- => (IS, IX)
」を参照します。
レコード ロック レコード ロック最も基本的なロックの種類
- ギャップ ロック ギャップ ロック
- ネクスト キー ロック
- これら 3 つのロックは、上記の
に対して実装された 3 つのアルゴリズム メソッドとして理解されます。ここでは、それらを一時的に次のように呼びます:
高次ロック
- AUTO-INC ロック自動インクリメント キー ロック
- 空間インデックスの述語ロック特別に使用される空間インデックス
- 上の 3 つは追加の拡張ロックです。
共有ロックを使用するには、
lock in share mode- を声明 。排他的ロックは、デフォルトで
- Insert、Update、および Delete
によって使用されます。ステートメントの後に
for updateを使用して表示します。
意図ロックはデータベース自体によって維持されます。 (主な機能は、テーブルがロックされているかどうかを記録するためにテーブル
をマークすることです) => そのようなロックがない場合、他のトランザクションがテーブルをロックしたいとき、テーブル全体にアクセスする必要があります。ロックのスキャンも面倒です。非効率的な。それが、意図ロックが存在する理由です。 補足: Mysql では何がロックされていますか?
ロックされているのはインデックスなので、この時点で「インデックスを作成しないとどうなるのですか?」と尋ねる人がいるかもしれません。
上でインデックスの存在について説明しました。ここで復習してみましょう。次のような状況がいくつかあります。
クラスター化インデックス (クラスター化インデックス) である主キーを作成しました。完全なデータ
)- 主キーはありませんが、一意のキーがあり、それがnullではない場合、
このキーに基づいてクラスター化インデックスが作成されます
- その場合、上記 2 つのどちらでもありません。心配しないでください。innodb は
rowid
と呼ばれるものを維持し、この ID ## に基づいて - クラスター化インデックスを作成します。
#したがって、テーブルにはインデックスが必要です。したがって、ロックをロックするためのインデックスが常に存在します。
明示的に
index
ロック クエリ
を実行したい場合、データベースは実際にはどのデータをチェックすべきかを知りません。テーブルを使用することもできます。したがって、単純にテーブル全体をロックします
。
- たとえば、
補助インデックス
に書き込みロックを追加する場合は、select * from where name = 'xxx' for update
最後に、returnテーブル
チェック主キーの情報を確認するため、この時点では、補助インデックス
をロックすることに加えて、主キーインデックス
##最初に、上記の 3 つの概念について、次のようなデータのセットがあります: 主キーは 1、3、6、9 です。 保存時は、 x 1 x 3 x x 6 x x x 9 x....
レコードロック、つまり 1、3、6、9 の各レコードをロックします。 ギャップ ロック、各 #xx
、(-∞,1)、(1,3)、(3,6)、(6,9)、(9, ∞) のレコード ギャップをロックします。 ロックする場合、ロックされるのは (-∞,1]、(1,3]、(3,6]、(6,9]、(9, ∞]) です。左開きと右閉じの区間まず、この 3 つのロックはすべて
排他ロック
select * from xxx where id = 3 for updatewhen
- When
- select * from xxx where id = 5 for update
, a gap lock is generated => (3,6) is locked. ここで特に注意してください。 : 競合はありません
Update - に
select * from xxx where id = 5 を選択すると、一時的なキー ロックが生成されます => locked (3,6] 、mysql は次の方法で一時的なキー ロックを使用します条件 1 と 2 が満たされない場合、すべての行ロックは一時的なキー ロックです
-
元の質問に戻ります。ここで
レコード ロック行ロック は、他の行ロックを防止します。トランザクションの変更または削除を防止します。
- 他のトランザクションの追加を防ぎます。
- ギャップ ロックとレコード ロック
を組み合わせて
Next- キー ロックを形成します。共同で解決します。
RR レベルデータ書き込み時のファントム読み取り問題。
ロックに関しては逃れる方法はありませんが、デッドロックについて話しましょう
後で確認してくださいデッドロックが発生しました
#「innodb_row_lock_%」のようなステータスを表示
Innodb_row_lock_current_waits 現在待機しているロックの数- Innodb_row_lock_time 合計の時間wait
Innodb_row_lock_time_avg 平均待機時間
- Innodb_row_lock_time_max 最大待機時間
- Innodb_row_lock_waits 合計で発生した待機数
- select * from information_schema.INNODB_TRX
- 現在実行中のトランザクションとロックされたトランザクションを表示できます
show full processlist - =
select * from information_schema.processlist
どのトランザクションをクエリできますかユーザー - はどのマシン ホストとどのポート上にありますか
#ステータスと時刻
デッドロックの防止
データへのアクセス順序を確保する
where を使用する場合はインデックスの使用を避けてください (これによりテーブルがロックされ、デッドロックが発生する可能性が高くなるだけでなく、ただし、パフォーマンスは低下します)
- 最適化の章
- サブデータベースとサブテーブル
- データ ソースの動的選択
- エンコーディング層 -- AbstractRoutingDataSource の実装 => フレームワーク層 -- Mybatis プラグインの実装 => ドライバー層 - シャーディング JDBC (複数のデータ ソースを構成し、カスタム実装戦略に従ってデータを個別のデータベースとテーブルに保存) コア プロセス、SQL 解析 => 実行最適化 => SQL データベース ルーティング => SQL 変更 (例:テーブルの分割とテーブル名の変更)=>SQL 実行=>結果のマージ) => プロキシ層 -- Mycat (データベースへのすべての接続から独立しています。すべての接続は Mycat によって行われ、他のサービスは Mycat にアクセスしてデータを取得します) => サービス層 - 特別な SQL バージョン
MYSQL を最適化する方法
結局のところ、MYSQL をより良く使用するために多くの知識を学びましたので、実際にそれを実行して完全な最適化システムを確立しましょう
#クエリのパフォーマンスを向上させたい場合は、このクエリ実行プロセス
、クライアント接続プールから開始できます。
では、接続プールは多ければ多いほど良いのでしょうか? 興味のある方はこの記事を読んでください: プールのサイジングについて毎回接続を作成したり破棄したりすることを避けるために、接続プールを追加します。
大まかに要約します:
- SQL の同時実行は、接続数が増加しても高速化されません。なぜ? 10,000 の接続を同時に実行している場合、10 の接続よりもはるかに高速ではないでしょうか? 答えは「ノー」で、高速ではないだけでなく、ますます遅くなります。
- コンピュータでは、
CPU
だけが実際にスレッド
を実行できることを誰もが知っています。オペレーティング システムはタイム スライシング
テクノロジを使用しているため、1 つのCPU コア
が複数のスレッド
を実行していると考えられます。 - しかし、実際には、以前の
CPU
は、一定の期間中に 1 つの
スレッドしか実行できないため、同時実行性をどのように高めても
CPUは、この期間内にまだ限られた量のデータしか処理できません。
では、 - CPU
がそれほど多くのデータを処理できない場合でも、どのようにして速度が低下するのでしょうか?
タイム スライシングのため、複数のスレッドが
「同時に実行」しているように見えても、実際にはスレッド間でのコンテキストの切り替え
に非常に時間がかかりますしたがって、スレッドの数が CPU コアの数を超えると、スレッドの数を増やしてもシステムは遅くなるだけで、高速になることはありません。
- コンピュータでは、
- たとえば、私たちが使用している機械式ハードディスクの場合、ディスクを回転させ、特定の場所にアドレス指定してから、
- I/O
- 操作を実行する必要があります。このとき、
CPU
は、他のスレッド
に時間をスライスして、処理効率と速度を向上させることができますしたがって、機械式ハード ドライブを使用している場合は、通常、高い同時実行性を維持するために接続を追加できます。
- ただし、SSD を使用している場合は、 I/O
- 待ち時間が非常に短いため、あまり多くの接続を追加することはできません
スレッド数 = ((コア数 * 2) 有効ディスク数) - 操作を実行する必要があります。このとき、
- 。たとえば、
i7 4 コア 1 ハードディスク
マシンは 4 * 2 1 = 9この式をご存知でしょうか?これはデータベース接続だけでなく、任意の
多数の CPU コンピューティングおよび I/O シナリオ - 例: 最大スレッド数の設定など
3 番目-パーティ キャッシュ
同時実行性が非常に大きい場合、それらすべてをデータベースにヒットさせることはできません。クライアントがクエリのためにデータベースに接続するときに、
Redis# などのサードパーティ キャッシュを追加します。
データベースの 1 つでは大規模な同時実行に耐えられないため、さらにいくつかのマシンを追加してみてはいかがでしょうか? マスター/スレーブ レプリケーションの概略図##データベースをクラスター モードでデプロイする
この図から、Mysql のマスター/スレーブ レプリケーション
読み取り/書き込み分離
非同期レプリケーション# が簡単にわかります。 ## 特性。
をヒント:
バイナリ ログ- リレー ログ
- に書き込んだ後、
スレーブ
は最新のバイナリ ログ位置##を読み取ります。 # は
master infoに記録され、次回はこの位置から直接取得されます。
マスター/スレーブ レプリケーションのさまざまな方法
上記の
非同期
トランザクション
完全同期レプリケーションを導入する必要があります。マスター ノードが最初に書き込みを行い、その後、すべてのスレーブが許可されます。すべてのスレーブは書き込み成功を返す前にノードがデータの書き込みを完了する必要があります。これは書き込みパフォーマンスに大きな影響を与えます。
準同期レプリケーションでは、書き込みデータが 1 つある限り、それが考慮されます成功。 (半同期レプリケーションが必要な場合は、マスター ノードとスレーブ ノードの両方で semisync_mater.so プラグインと semisync_slave.so プラグインをインストールする必要があります)
- GTID (グローバル トランザクション ID) レプリケーション (マスター ライブラリがレプリケートされる場合)マスターとスレーブの同期レプリケーション遅延により、自動
- フェイルオーバー アクションが実現されます。つまり、マスター ノードがハングアップし、スレーブ ノードが選択された場合、データ損失が発生する可能性があります。素早く自動的に回避します。
- クラスター高可用性ソリューション
NDB
- Glaera Cluster for MySQL
- MHA (MySQL のマスター-マスター レプリケーション マネージャー)、MMM (MySQL マスター ハイ アベイラブル)
- MGR (MySQL グループ レプリケーション) => MySQL クラスター
- 分割テーブル
- データを分類して別のテーブルに分割し、単一のテーブルへの過度の影響を軽減します ロック操作
テーブル構造
- 合理的なフィールド タイプの設計
- 合理的なフィールド長の設計
3. オプティマイザーと実行エンジン
遅いlog
をオンにすると、
show_query_log
が実行され、実行時間が変数long_query_time
を超える SQL ステートメントが記録されます。mysqldumpslow /var/lib/mysql/mysql-slow.log
を使用できます。これよりも洗練された分析を提供できるプラグインが多数あるため、ここでは詳しく説明しません。分析 SQL の説明
SQL を作成した後は、
を行う必要があります。explain
1. ドライバー テーブル - たとえば、
left/right join
の乱用はパフォーマンスの低下につながります-
left/right join
を使用すると、直接指定されます。 MYSQL では、テーブルの関連付けにデフォルトでNest ループ結合
が使用されます (つまり、駆動テーブル
の結果セットがループの基本データとして使用され、次に、次に関連付けられたテーブルが、このセット内のデータの各部分でフィルター処理され、最後に結果がマージされて、よく一時テーブル
) と呼ばれるものが得られます。 - 駆動テーブル
のデータが
100 万レベルの場合、この結合テーブルのクエリがどれほど遅くなるか想像できるでしょう。しかし、その一方で、
小さいテーブルを
駆動テーブルとして使用すると、数千万のテーブルの
indexの助けを借りてクエリが非常に高速になる可能性があります。
。誰を
駆動テーブル - として使用すべきかわからない場合は、オプティマイザに決定させてください。たとえば、次のようになります。
select xxx from table1, table2, table3 where ... ·
、オプティマイザは、少数のクエリ レコード行を含むテーブルを駆動テーブルとして使用します。ドライバー テーブル
を自分で指定したいだけの場合は、 - Explain
武器を入手してください。
Explainの結果のうち、最初の 1 つは
Basic driver tableSort です。同様に、異なる
テーブル をソートすると、パフォーマンスに大きな違いがあります。マージされた結果である - 一時テーブルではなく、
ドライバー テーブル
をソートしようとします。 # 分類する。つまり、実行計画にusingtemporary
が表示され、最適化を実行する必要があります。2. 実行プランの各パラメーターの意味
通常のクエリ
および- 複雑なクエリ
- (ユニオンクエリ、サブクエリなど)
SIMPLE
、クエリにサブクエリまたはUNION-
PRIMARY
が含まれていない場合、クエリに 複雑なクエリ - サブ構造が含まれる場合は、主キー クエリ
SUBQUERY
を使用し、 サブ構造を - select# に含める必要があります。 ## または
where
クエリDERIVED
、
from にサブクエリ -
UNION RESULT
が含まれます、
union からの テーブル クエリ サブクエリ -
table 使用するテーブル名
type (アクセス タイプ)、必要な行の検索方法、上から下へのクエリ Speed
-
- const または system
定数レベルのスキャン、テーブルをクエリする最速の方法、system は const の特殊なケースです (テーブル内 データは 1 つだけ)
- #eq_ref
- 一意のインデックス スキャン
- 非一意のインデックス スキャン
- between、 などのインデックス範囲スキャン、およびその他の範囲クエリ
- (インデックス フル) すべてのインデックス ツリーをスキャン
- テーブル全体
- をスキャンします。テーブルまたはインデックス
- #possible_keys にアクセスする必要はありません。どのインデックスにアクセスするかを指定します。テーブル内のレコードを検索するために使用します。ここにリストされているインデックス
は、必ずしも
は - 一意のインデックス スキャン
- です。そうでない場合は、NULL
key_len: 使用されるインデックスによって占有されるバイト数
- ref:
index (キー)
と一緒に使用されるフィールドまたは定数 - rows: 合計でスキャンされた行数
- filtered (percentage): サーバー層でフィルターされたデータの量
Extra: 追加情報
- インデックスのみ
- 情報はインデックスから取得するだけで済みます。カバーインデックスを使用することもでき、クエリは非常に高速です。
-
- using where
- If the queryインデックスは使用しません。
サーバー
レイヤ フィルタリングで使用され、結果セットをフィルタリングするために where - を使用します。
impossible where
何もありませんでしたfound using filesort - (インデックスによる並べ替えがなく、他の並べ替え方法が使用される場合に限ります)、filesort
- (結果セットは、一時テーブルを介して一時的に保存してから計算する必要があります。) 一般に、この場合、
DISTINCT、並べ替え、およびグループ化
-
インデックス条件を使用します
プッシュダウンされます。前述したように、インデックスはプッシュダウンされます。サーバー層
このフィルタリング操作 はエンジン層にプッシュダウンされます -
#4. ストレージ エンジン
しかない場合は、 - If the queryインデックスは使用しません。
ストレージ エンジン
- を使用できます。一時データのみを使用します。
- memory
挿入、更新、クエリ
などの同時操作が多数ある場合は、 InnoDB を使用できます。 -
各レベルでの MYSQL 最適化に関する 5 つの回答 (上から下まで)
SQL とインデックス
- ハードウェアとオペレーティング システム
- さらに、データ クエリが遅い場合は、データベースをただやみくもに「最適化」するのではなく、ビジネス アプリケーション レベルから分析する必要があります。たとえば、データのキャッシュ、リクエストの制限などです。
- また次の記事でお会いしましょう
関連する無料学習の推奨事項: mysql ビデオ チュートリアル
- ストレージスペースの使用率が低いため、断片化が発生し、
以上がMYSQL の基礎となる原則を理解するのに役立つ記事の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









MySQLは、インストールが簡単で、強力で管理しやすいため、初心者に適しています。 1.さまざまなオペレーティングシステムに適した、単純なインストールと構成。 2。データベースとテーブルの作成、挿入、クエリ、更新、削除などの基本操作をサポートします。 3.参加オペレーションやサブクエリなどの高度な機能を提供します。 4.インデックス、クエリの最適化、テーブルパーティション化により、パフォーマンスを改善できます。 5。データのセキュリティと一貫性を確保するために、バックアップ、リカバリ、セキュリティ対策をサポートします。

NAVICATプレミアムを使用してデータベースを作成します。データベースサーバーに接続し、接続パラメーターを入力します。サーバーを右クリックして、[データベースの作成]を選択します。新しいデータベースの名前と指定された文字セットと照合を入力します。新しいデータベースに接続し、オブジェクトブラウザにテーブルを作成します。テーブルを右クリックして、データを挿入してデータを挿入します。

NAVICAT自体はデータベースパスワードを保存せず、暗号化されたパスワードのみを取得できます。解決策:1。パスワードマネージャーを確認します。 2。NAVICATの「パスワードを記憶する」機能を確認します。 3.データベースパスワードをリセットします。 4.データベース管理者に連絡してください。

MySQLは、オープンソースのリレーショナルデータベース管理システムです。 1)データベースとテーブルの作成:createdatabaseおよびcreateTableコマンドを使用します。 2)基本操作:挿入、更新、削除、選択。 3)高度な操作:参加、サブクエリ、トランザクション処理。 4)デバッグスキル:構文、データ型、およびアクセス許可を確認します。 5)最適化の提案:インデックスを使用し、選択*を避け、トランザクションを使用します。

Passwordが暗号化された形式で保存されているため、MariadbのNavicatはデータベースパスワードを直接表示できません。データベースのセキュリティを確保するには、パスワードをリセットするには3つの方法があります。NAVICATを介してパスワードをリセットし、複雑なパスワードを設定します。構成ファイルを表示します(推奨されていない、高リスク)。システムコマンドラインツールを使用します(推奨されません。コマンドラインツールに習熟する必要があります)。

手順に従って、NAVICATで新しいMySQL接続を作成できます。アプリケーションを開き、新しい接続(CTRL N)を選択します。接続タイプとして「mysql」を選択します。ホスト名/IPアドレス、ポート、ユーザー名、およびパスワードを入力します。 (オプション)Advanced Optionsを構成します。接続を保存して、接続名を入力します。

MySQLとSQLは、開発者にとって不可欠なスキルです。 1.MYSQLはオープンソースのリレーショナルデータベース管理システムであり、SQLはデータベースの管理と操作に使用される標準言語です。 2.MYSQLは、効率的なデータストレージと検索機能を介して複数のストレージエンジンをサポートし、SQLは簡単なステートメントを通じて複雑なデータ操作を完了します。 3.使用の例には、条件によるフィルタリングやソートなどの基本的なクエリと高度なクエリが含まれます。 4.一般的なエラーには、SQLステートメントをチェックして説明コマンドを使用することで最適化できる構文エラーとパフォーマンスの問題が含まれます。 5.パフォーマンス最適化手法には、インデックスの使用、フルテーブルスキャンの回避、参加操作の最適化、コードの読み取り可能性の向上が含まれます。

NAVICATでSQLを実行する手順:データベースに接続します。 SQLエディターウィンドウを作成します。 SQLクエリまたはスクリプトを書きます。 [実行]ボタンをクリックして、クエリまたはスクリプトを実行します。結果を表示します(クエリが実行された場合)。
