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