前言
再版
有哪些方法
転載元:https://www.changchenghao.cn/n/174426.html
-
EXPLAIN
はMySQLの最適化を行います。SQL実行プランを表示するには、EXPLAINをうまく利用する必要があります。
これは簡単な例で、焦点を当てたいデータにラベルを付けます(1、2、3、4、5)。
- タイプ列、接続タイプ。優れたSQLステートメントは、少なくとも範囲レベルに到達する必要があります。すべてのレベルに終止符を打つ。
- キー列、使用されるインデックス名。インデックスが選択されていない場合、値はNULLです。必須の索引付けを採用できます。
- key_len列、インデックスの長さ。
- 行列、スキャン行の数。この値は推定値です。
- 追加の列、詳細な説明。一般的な不適切な値は次のとおりであることに注意してください:filesortの使用、temporaryの使用。
-
SQLステートメントのINの値は多すぎないようにする必要があります
-
SELECTステートメントはフィールド名を指定する必要があります
-
必要なデータが1つだけの場合は、制限1を使用します
-
並べ替えフィールドでインデックスを使用しない場合は、並べ替えをできるだけ少なくしてください
-
制限条件の他のフィールドにインデックスがない場合は、使用するか、できるだけ少なくします
-
ユニオンの代わりにすべてユニオンを使用してみてください
-
)ORDER BY RANDを(使用しないでください
からIDを選択するdynamic
のrand()リミット1000ため、
上記のSQL文は、に最適化することができます
から。SELECT IDdynamic
t1の参加(選択ランド()*(選択最大(ID)からdynamic
)NIDなど) t1.idのt2> t2.nidlimit 1000; -
inとexists、notinとnotexistsを区別する
select * from table A where id in(select id from table B)
上記のSQLステートメントは、
select * from table A where presents(select * from table B where tableB )と同等です。 id = table A.id)
inとexistsの区別は、主に駆動シーケンスの変更によって引き起こされます(これがパフォーマンス変更の鍵です)。存在する場合、外側のテーブルが駆動テーブルであり、最初にアクセスされます。 。INの場合、サブクエリが最初に実行されます。したがって、INは外面が大きく内面が小さい場合に適しており、EXISTSは外面が小さく内面が大きい場合に適しています。
存在しない、存在しないということに関しては、存在しないを使用することをお勧めします。これは効率の問題であるだけでなく、論理的な問題がある可能性があります。存在しないものを置き換えるSQLステートメントを効率的に作成するにはどうすればよいですか?
元のSQLステートメント:
selectcolname…froma.idがないテーブル(select b.id from B table)
効率的なSQLステートメント:selectcolname
…fromAテーブル左結合Bテーブルonwhere a.id = b.id where
The b.idによって取得された結果セットがnullの場合、次の図に示されています。テーブルAのデータはテーブルBにはありません。
-
妥当なページング方法を使用して、ページングの効率を向上させ
ますselect id、name from product limit 866613、20
上記のSQLステートメントをページングに使用すると、テーブルデータの量が増えると、制限ページングクエリを直接使用することが増えることがあります。遅い。
最適化の方法は次のとおりです。前のページの最大行数のIDを取得し、この最大IDに従って次のページの開始点を制限できます。たとえば、この列では、前のページの最大IDは866612です。SQLは次のように記述できます
。selectid、name from product where id> 866612 limit 20 -
セグメントクエリ
一部のユーザー選択ページでは、一部のユーザーが長すぎる時間範囲を選択し、クエリが遅くなる場合があります。主な理由は、スキャンラインが多すぎることです。この時点で、プログラム、セグメントを使用してクエリを実行し、トラバーサルをループし、結果をマージして表示することができます。
以下に示すSQLステートメントでは、スキャンされた行が数百万レベルを超える場合に、セグメント化されたクエリを使用できます。
-
where句のフィールドのnull値の判断は避けてください。nullの
判断により、エンジンはインデックスの使用をあきらめ、全表スキャンを実行します。 -
LIKE "%name"やLIKE "%name%"などの%プレフィックスファジークエリを使用することはお勧めしません。この種のクエリでは、インデックスが失敗し、全表スキャンが実行されます。ただし、LIKE "name%"は使用できます。
%name%をクエリする方法は?
:インデックスが秘密のフィールドに追加されているが、下の図に示すように、説明の結果で使用されていない
書き込みSQLは、これらの19件の最適化の原則を覚えて、そして効率が少なくとも3倍に増加している。
これを解決するために、どのように問題、答え:フルテキストインデックスを使用してください。
クエリでは、dynamic_201606のselect id、fnum、fdstをよく使用します。user_nameは「%zhangsan%」のようになります。このようなステートメントの場合、通常のインデックスはクエリ要件を満たすことができません。幸い、MySQLには、役立つフルテキストインデックスがあります。
SQL構文のフルテキストインデックスの作成は次
のとおりですdynamic_201606
。ALTERTABLEtheADD FULLTEXT INDEXidx_user_name
(user_name
);
SQLステートメントのフルテキストインデックスの使用は次
のとおりです。SELECT上記のID、FNUM、fdst from dynamic_201606 WHERE match(user_name) Against( 'zhangsan' in boolean the MODE);
注:フルテキストインデックスを作成する必要がある前に、DBAに連絡して作成できるかどうかを確認してください。同時に、クエリステートメントと通常のインデックスの違いに注意する必要があります。 -
where句のフィールドで式操作を実行することは避けてください。
例:
select user_id、user_project from user_base where age * 2 = 36;
フィールドで算術演算を実行すると、エンジンはインデックスの使用を中止します。次のように変更し
ます。selectuser_id、user_project from user_base where age = 36/2; -
where句の列フィールドの型が暗黙的な型変換で渡されたパラメーターの型と矛盾する場合に発生する型変換を回避するには、最初にwhereでパラメーター型を判別することをお勧めします。 -
共同インデックスの場合、左端のプレフィックスルールに従う必要があります。
たとえば、インデックスにはフィールドid、name、schoolが含まれます。idフィールドは直接使用することも、id、nameの順序を使用することもできますが、name ;学校はこのインデックスを使用できません。したがって、ジョイントインデックスを作成するときは、インデックスフィールドの順序に注意する必要があります。一般的に使用されるクエリフィールドが最初に配置されます。 -
必要に応じて、force indexを使用して、クエリを強制的にインデックスに移動させる
ことができます。MySQLオプティマイザは、SQLステートメントの取得に適していると思われるインデックスを使用する場合がありますが、使用するインデックスが目的のインデックスではない場合があります。このとき、forceindexを使用して、オプティマイザーにインデックスの使用を強制できます。 -
範囲クエリステートメントに注意してください
。ジョイントインデックスの場合、間、>、<などの範囲クエリがあると、後続のインデックスフィールドは無効になります。 -
JOIN最適化に関しては、
LEFT JOIN Aテーブルが駆動テーブルであり、INNER JOIN MySQLが駆動テーブルとして機能するデータの少ないテーブルを自動的に検出し、RIGHT JOINBテーブルが駆動テーブルです。
注:
1)MySQLには完全結合はありません。次の方法で解決できます:
select * from A left join B on B.name = A.name where B.name is nullunion allselect * from B;
2)左結合を回避するために内部結合を使用する:
結合クエリに参加しているテーブルは少なくとも2つあり、通常はサイズに違いがあります。接続方法が内部結合の場合、MySQLは他のフィルタリング条件なしで駆動テーブルとして小さなテーブルを自動的に選択しますが、左結合は駆動テーブルの選択、つまりテーブルの名前で左駆動の原則に従います。左側の結合の左側にあるドライビングテーブル用。
3)インデックスの合理的な使用:
ドリブンテーブルのインデックスフィールドは、onの制限付きフィールドとして使用されます。
4)小さなテーブルを使用して大きなテーブルを駆動する:
回路図から、ドライブテーブルを減らすことができれば、ネストされたループ内のループの数を減らしてIOとIOの合計量を減らすことができることが直感的にわかります。CPU操作の数。
5)STRAIGHT_JOINを上手に使用します。
内部結合はMySQLによってテーブルを駆動するために選択されますが、特別な場合には、「filesortの使用」や「groupbyやorderby」などの「temporaryの使用」などの別のテーブルを駆動テーブルとして選択する必要があります。STRAIGHT_JOINは接続順序を強制します。STRAIGHT_JOINの左側のテーブル名は駆動テーブルであり、右側は駆動テーブルです。STRAIGHT_JOINを使用するための前提条件は、クエリが内部結合であるということです。これは内部結合です。STRAIGHT_JOINは、他のリンクには推奨されません。そうしないと、クエリ結果が不正確になる可能性があります。
この方法では、時間を3分の1に短縮できる場合があります。