1. MySQLの一般的なボトルネック
CPU:
- SQLで大量のデータを比較、相関、ソート、およびグループ化します。最大のプレッシャーは比較です。
IO:
- インスタンスメモリは、データのキャッシュや並べ替えのニーズを満たすことができないため、多くの物理IOが発生します。
- クエリの実行効率が低く、スキャンするデータ行が多すぎます。
ロック:
- 不適切なロック設定は、スレッドのブロックとパフォーマンスの低下につながります。
- デッドロック、スレッド間のリソースのクロスコール、結果としてデッドロックが発生し、プログラムがスタックします。
サーバーハードウェアパフォーマンスのボトルネック:
- top、free、iostat、およびvmstatは、システムパフォーマンスのステータスを表示します。
2.パフォーマンス分析について説明する
1.コンセプト
EXPLAINキーワードを使用すると、SQLクエリステートメントを実行するオプティマイザをシミュレートできるため、MySQLがSQLステートメントを処理する方法がわかります。クエリまたはテーブル構造のパフォーマンスボトルネックを分析します。
使用法:Explain + SQLステートメント。
Explainの実行後に返される情報:
あなたにできること:
- テーブルの読み取り順序
- 使用できるインデックス
- データ読み取り操作の操作タイプ
- 実際に使用されているインデックス
- テーブル間の参照
- オプティマイザがクエリする各テーブルの行数
2.準備について説明する
CREATE TABLE t1(id INT(10) AUTO_INCREMENT,content VARCHAR(100) NULL , PRIMARY KEY (id));
CREATE TABLE t2(id INT(10) AUTO_INCREMENT,content VARCHAR(100) NULL , PRIMARY KEY (id));
CREATE TABLE t3(id INT(10) AUTO_INCREMENT,content VARCHAR(100) NULL , PRIMARY KEY (id));
CREATE TABLE t4(id INT(10) AUTO_INCREMENT,content VARCHAR(100) NULL , PRIMARY KEY (id));
INSERT INTO t1(content) VALUES(CONCAT('t1_',FLOOR(1+RAND()*1000)));
INSERT INTO t2(content) VALUES(CONCAT('t2_',FLOOR(1+RAND()*1000)));
INSERT INTO t3(content) VALUES(CONCAT('t3_',FLOOR(1+RAND()*1000)));
INSERT INTO t4(content) VALUES(CONCAT('t4_',FLOOR(1+RAND()*1000)));
3. id
クエリ内でのselect句または操作テーブルの実行順序を示す、一連の番号を含む選択クエリのシーケンス番号。
注:idが同じ場合は、グループと見なすことができ、上から下に順番に実行されます。すべてのグループで、id値が大きいほど優先順位が高くなり、早く実行されます。派生= DERIVED
懸念事項:ID番号の各番号は、独立したクエリを表します。SQLのクエリトリップの数が少ないほど、優れています。
4. select_type
select_typeはクエリのタイプを表し、主に通常のクエリ、結合クエリ、サブクエリなどの複雑なクエリを区別するために使用されます。
select_type属性 | 意味 |
---|---|
シンプル | 単純な選択クエリ、クエリにはサブクエリまたはUNIONが含まれていません |
一次 | クエリに複雑なサブパートが含まれている場合、最も外側のクエリはプライマリとしてマークされます |
派生 | FROMリストに含まれるサブクエリはDERIVED(派生)としてマークされ、MySQLはこれらのサブクエリを再帰的に実行し、結果を一時テーブルに格納します。 |
サブクエリ | サブクエリがSELECTまたはWHEREリストに含まれている |
従属サブクエリ | サブクエリがSELECTまたはWHEREリストに含まれていて、サブクエリが外側のレイヤーに基づいている |
キャッシュできないサブクエリ | キャッシュされたサブクエリを使用できません |
連合 | UNIONの後に2番目のSELECTが出現する場合、UNIONとしてマークされます。UNIONがFROM句のサブクエリに含まれている場合、外側のSELECTはDERIVEDとしてマークされます。 |
ユニオン結果 | UNIONテーブルから結果を取得するSELECT |
4.1シンプル
SIMPLEは単一のテーブルクエリを表します;
4.2 PRIMARY
クエリに複雑なサブパートが含まれている場合、最も外側のクエリがプライマリとしてマークされます。
4.3派生
FROMリストに含まれるサブクエリはDERIVED(派生)としてマークされ、MySQLはこれらのサブクエリを再帰的に実行し、結果を一時テーブルに格納します。
4.4サブクエリ
サブクエリはSELECTまたはWHEREリストに含まれています。
4.5従属サブクエリ
サブクエリはSELECTまたはWHEREリストに含まれ、サブクエリは外側のレイヤーに基づいています。
どちらも背後にある条件であり、サブクエリは単一の値であり、従属サブクエリは値のセットです。
4.6 UNCACHEABLE SUBQUREY
@@を使用してシステム変数を参照する場合、キャッシュは使用されません。
4.7ユニオン
UNIONの後に2番目のSELECTがある場合はUNIONとしてマークされ、UNIONがFROM句のサブクエリに含まれている場合は、外側のSELECTがDERIVEDとしてマークされます。
4.8ユニオン結果
SELECTを使用して、UNIONテーブルから結果を取得します。
5.テーブル
このデータはどのテーブルに基づいていますか。
6.タイプ
typeはクエリのアクセスタイプです。これはより重要な指標であり、最高から最低までの結果値は次のとおりです。
system> const> eq_ref> ref> fulltext> ref_or_null> index_merge> unique_subquery> index_subquery> range> index> ALL
一般に、クエリが少なくとも範囲レベル、できればrefに到達することを確認する必要があります。
掌握:system> const> eq_ref> ref> range> index> ALL
6.1システム
テーブルにはレコードが1行しかありません(システムテーブルと同じ)。これはconstタイプの特別な列であり、通常は表示されません。これも無視できます。
6.2 const
1回のインデックス作成で見つかったことを示し、constを使用して主キーまたは一意のインデックスを比較します。一致するデータは1行だけなので、主キーがwhereリストに配置されると、MySQLはクエリを定数に変換できます。
6.3 eq_ref
一意のインデックススキャン:インデックスキーごとに、テーブル内の1つのレコードのみが一致します。主キーまたは一意のインデックススキャンで一般的に使用されます。企業にはCEOが1人、開発者が多数いることがわかります。
6.4参照
一意でないインデックススキャンは、単一の値に一致するすべての行を返します。基本的には、インデックスアクセスです。単一の値に一致するすべての行を返します。ただし、条件を満たす複数の行が見つかる場合があるため、検索とスキャンの混合に属している必要があります。
役に立たないインデックスの前:
インデックス作成後:
6.5の範囲
指定された範囲の行のみを取得し、インデックスを使用して行を選択します。キー列を示し、一般的に、あなたの文に表示されているインデックスの使用場所をbetween、<、>、in
スキャン、インデックススキャン範囲が原因でいくつかの点で、全表スキャンよりも優れている、と結論インデックス内の別のポイントのみがスキャンなしで起動する必要があることを他のクエリすべてのインデックス。
6.6インデックス
インデックスの発生は、sqlがインデックスを使用するが、インデックスでフィルタリングする必要がないことです。通常、オーバーレイインデックスが使用されるか、インデックスがソートおよびグループ化に使用されます。
フルインデックススキャン。インデックスとALLの違いは、インデックスタイプはインデックスツリーのみを走査することです。通常、インデックスファイルはデータファイルよりも小さいため、これはALLよりも高速です。
(つまり、すべてとIndexは両方ともテーブル全体を読み取りますが、インデックスはインデックスから読み取られ、すべてはハードディスクから読み取られます)
6.7すべて
全表スキャンでは、全表を走査して一致する行を見つけます。
6.8 index_merge
クエリプロセスでは、複数のインデックスの組み合わせが必要です。これは通常、SQLでorキーワードを使用して表示されます。
6.9 ref_or_null
関連付け条件とnull値の両方を必要とするフィールドの場合。クエリオプティマイザーは、ref_or_nullを使用してクエリを結合することを選択します。
6.10 index_subquery
インデックスを使用してサブクエリを相互に関連付け、テーブル全体をスキャンする必要はなくなりました。
6.11 unique_subquery
接続タイプはindex_subqueryに似ています。サブクエリの一意のインデックス。
備考:一般的に言えば、クエリが少なくとも範囲レベルに到達していることを確認する必要があります。
7.可能性のあるキー
このテーブルに適用される可能性のある1つ以上のインデックスを表示します。クエリに関係するフィールドにインデックスがある場合、そのインデックスはリストされますが、実際にはクエリで使用されない可能性があります。
8.キー
使用される実際のインデックス。NULLの場合、インデックスは使用されません。
クエリでカバリングインデックスが使用されている場合、インデックスとクエリの選択フィールドが重複しています
9. key_len
インデックスで使用されるバイト数を示します。この列を使用して、クエリで使用されるインデックスの長さを計算できます。key_lenフィールドは、インデックスが完全に使用されているかどうかを確認するのに役立ちます。ken_lenが長いほど、インデックスがより完全に使用されます。
計算方法:
①int= 4; varchar(20)= 20; char(20)= 20などのインデックス上のフィールドのタイプと長さを確認します
。②varcharやcharなどの文字列フィールドの場合、文字セットに異なる値を掛ける必要があります3を掛けるutf-8のような値、2を掛けるGBK③2バイト
を追加する動的文字列varchar④
空のフィールドに1バイトを追加する
最初のグループ:key_lenのバイト長=エージ+名前のバイト長= 4 + 1 +(20 * 3 + 2)= 5 + 62 = 67
秒のグループ:key_lenのバイト長=年齢= 4 + 1 = 5
10.参照
可能な場合は定数を使用して、インデックスのどの列を表示します。インデックス列の値を見つけるために使用される列または定数。
11.行
rowsカラムは、MySQLがクエリを実行するときにチェックする必要があると考える行数を示します。少ないほど良い!
12.追加
他の列での表示には適さないが、非常に重要な追加情報が含まれています
12.1 filesortの使用
mysqlは、テーブルのインデックス順に従って読み取るのではなく、外部インデックスを使用してデータをソートすることを説明します。インデックスで完了できないMySQLのソート操作は、「ファイルソート」と呼ばれます。
filesortのケースが表示されます:
最適化後、filesortのケースは表示されなくなります。
クエリ内のソートされたフィールド。ソートされたフィールドがインデックスでアクセスされる場合、ソート速度が大幅に向上します。
12.2一時的な使用
一時テーブルを使用して中間結果を保存する場合、MySQLはクエリ結果をソートするときに一時テーブルを使用します。通常、order byおよびgroup by query group byで使用されます。
最適化前:
12.3インデックスの使用
インデックスを使用すると、対応する選択操作がカバリングインデックス(Covering Index)を使用して、テーブルのデータ行へのアクセスを回避する(テーブルに戻るのを回避する)ことを示します。whereが同時に表示される場合は、インデックスがインデックスキー値検索の実行に使用されていることを示します。whereが同時に使用されていない場合は、インデックスを使用して検索を実行するのではなく、インデックスがデータの読み取りにのみ使用されることを示します。インデックスを使用して、ソートまたはグループ化します。
12.4 whereの使用
whereフィルターが使用されていることを示します
12.5結合バッファの使用
接続キャッシュが使用されます。
12.6不可能
where句の値は常にfalseであり、タプルの取得には使用できません。
12.7離れて最適化されたテーブルの選択
GROUPBY句がない場合、MIN / MAX操作はインデックスに基づいて最適化されるか、COUNT(*)操作はMyISAMストレージエンジン用に最適化されます。実行ステージが計算されるまで待つ必要はなく、クエリ実行プラン生成のステージで最適化が完了します。
innodbの場合:
Myisamの場合:
ウォームアップケース;
インデックスインタビューの質問:
次のSQLで使用されるインデックスの分析:
c3は、
グループ化ではなくソートに使用されます。基本的に、すべてのソートが必要であり、不適切な場合は一時テーブルが存在します。