この記事では、SQLベースのある程度であるが、そのようなSQL人にはかなりはっきりしていないインデックスチューニングモードの使用などの問題がある場合は、彼が使用する方法を指摘しました。
この記事では、純粋なオリジナルではありません以前のブログの組み合わせで、自分のブログの要約を書きます。
MySQLは、使用の集まりに参加する:https://blog.csdn.net/lukabruce/article/details/80568796
インデックス、サブライブラリーのサブテーブル、SQLの文言などは、SQLパフォーマンスに影響します。
コンセプト:
1.データベースのトランザクションACID特性
データベーストランザクションの4特徴:
アトミック(原子): トランザクションにおける複数の動作、積分、または成功もしくは失敗であり、全か無か。
一貫性(整合性): トランザクション操作後、データベースの中の状態ビジネス・ルールは同じであり、例えば、各転送後、Bアカウントは、不変の総量、
分離(単離): 同じような複数のトランザクションの連続実行との間には、互いに影響を及ぼさない、
永続的な(耐久性): トランザクションがコミットされた後、永続的なストレージに永続化。
RCおよびRR分離レベルとの間の3 MySQLの差
MySQLのデータベースのデフォルト分離レベルRRが、現実には、RCとRR分離レベルの使用が多くあるということです。淘宝網のように、RC網易は、分離レベルを使用しています。だから、どのような違いMySQLのRCとRRでそれをしませんか?私たちはどのように選ぶのですか?デフォルトのRR分離レベルとしてなぜMySQLのそれ?
4. RCロックの観点からRR差
1>明らかRR支持ギャップロック(ネクストキーロック)、RCは隙間ロックはなかったです。MySQLはファントム読み取りの問題を解決するためにRRギャップロックの必要があるため。RCの分離レベルとファントム読み取りを読んで、またとないすることが許可されています。そのため、RCの同時実行はRRよりも一般的に優れています。
2(これは、「二段階ロック原理」を損なうであろうが)> RCの分離レベルは、条件が記録条件に行ロックを満たしていないフィルターを通過した後、解放される;しかしRR分離レベル、条件を満たしていない場合であってもレコードは、行ロックとギャップロックを解除しません。観点からロックには、RCの同時実行性が良くRRよりである必要があります。追加のインサートをtが選択に... sからテーブル上のどこの声明ロックは同じではありません。
5.データベースがロックされたレビューや線のトランザクション
二つ、MySQLの行ロック、テーブルロック
MyISAMテーブルのためにロックされたテーブルを選択し、それが待機状態にある他のオペレーティングハングアップにつながります。
InnoDBのテーブルでは、テーブルをロックしない]を選択。実際には、ここでスナップショットを使用します。スナップショットは、ここでは説明しません。
共通のInnoDB、選択...更新のために、+ IDまたは一意のインデックスフィールドフィルタは、それ以外の場合は、テーブルロックにつながる場所に注意を払うようにしてください。
最適化のヒント:
1.サーバーの最適化、例えばmax_connection大きな変化は、修正CONNECTION_TIMEOUT
2.最適化クライアント接続、多重接続プール
3.アーキテクチャレベル。
1)キャッシュ(例えばRedisの)を使用。
2)散開星団、別々の読み取りおよび書き込みがない場合。
3)クラスタが遅い、またどのように何百万ものデータ量を想定して、読み取りと書き込みの分離場合でも、その後、サブライブラリーサブテーブル
4.設定slow_query_logは、実行時間を分析し、長い時間のために、設定されたSQLが、また、特定のプロパティの消費量を超え、統計解析ツールがmysqldumpslowスロークエリbinディレクトリで使用することができます。
SQLの最適化:
ページングクエリがあまりにも複雑になっている場合は1、あなたは、直接詳細はバーストデータ列を指定したチェック、ページングされたデータを見つけることができます。
パフォーマンスへの影響はあまり大きくないですが、時間がどこ背中に書き込みにかかることができる場所前に書かれた2.caseとき声明、
ページ数が増加すると、検索効率が低い、リミット]タブを使用して大量のデータを3.mysql。
製品限界10、20 0.016秒SELECT * FROM
製品限界から選択* 100、20 0.016秒
製品限界10000、20 0.094 SELECT * FROM秒
製品の制限400000、20 3.229 SELECT * FROM秒
ページングクエリースピードアップするために、インデックステーブルの使用をカバーする
文は(インデックスをカバー)のみインデックス列が含まれている場合は、我々はすべてのノウハウを、インデックスクエリの使用は、このような状況はすぐに照会します。
限界20(ID制限866613、1によって製品注文から選択ID)WHERE ID> =製品SELECT * FROM或者
SELECT * FROM製品a.ID = b.id ON B(ID制限866613、20で製品注文のIDを選択)JOIN
0.2秒のクエリ時間!
ここVTYPE = 1つの限界90000,10収集からIDを選択し; //検索(VTYPE、ID)は、複合インデックスを追加しますすばやく
2.インデックス作品
MySQLのInnoDBは今主に使用されているインデックスツリー構造B +、B +ツリーが絶対的にバランスされた木は、それが右または左に行くのデータの特定の部分を知っている必要があり、スピードアップするために、メインメモリとハードディスクドライブ間の動作IO良い削減することができクエリの速度。(ケース:Bは、複数の検索ツリー、Bツリー、および各種データであるリーフノードの中に格納され、リーフノードがポインタによって接続されている間バランスバイナリツリーと同等ではなくバランスは木を持っています。)
一般的にのみ(Nログ)O B +ツリーは、なぜB +ツリーを選択しながら、一般的な使用のB +ツリーのストレージ構造のMySQLのインデックスは、実際には、データ(1)O、低複雑性を見つけるためにハッシュ構造記憶、ハッシュ構造を持っていますか?
分析:
1.なぜそれがバイナリツリーはないですか?
私たちは、ディスクIOの影響を考慮する必要があるので、非常に遅いメモリに相対的です。データベースインデックスは、ディスク上に格納され、データの量は、全体的なインデックスは、メモリの全てにロードすることができない場合には、各ディスクページ(インデックスツリーのノードに対応する)ずつロードされことができます。だから我々はIOの数を減らしたいです
2.なぜハッシュを使用していませんか?
そしてディスク上に一般的にメモリB +ツリー設計にロードされると、大量のデータがそうでないことがあり、データベース内のインデックスは、検索効率を向上させるために、ツリーの下の高さが、負荷バッチにデータを可能にすることができます。
これと関連したビジネスシナリオ。あなたはデータのみを選択した場合、それは確かに速いハッシュです。しかし、データベースは、多くの場合、秩序によるB +ツリーインデックスに、この時間を、複数を選択し、リスト、より速く、多くのそのクエリの効率比ハッシュをリンクされています。
一般的に、どのできるだけで、B +ツリーインデックスは、左またはツリーの右へのパスからどの表情の下に知っていない使用しているため、インデックスを取っていない<>はヌルたもので、丸暗記、非常に単純ではありません、ではない知っていますここで全表検索、非効率性は、基礎となるの共同指数は、私は理解していない以上、検証、です。
上の栗の場合、インデックス列のデータ長が長すぎることを我々はすべて知っているが、インデックスの効率性に影響を与えますが、実際は、なぜでしょうか?
実際に、使用されるB +ツリーインデックスMySQLのため、すべてのデータは、カラムサイズの株式指数が大きすぎるので、それは各データ・ストレージのためのリーフノードにつながる、リーフノード上に配置され、その結果、あまりにも多くのことはできませんより多くの葉を思われる、より多くの葉が低いので、効率上、木、深い層の数の層数の増加、そして時に行った回数も増加見つけるIOにつながります。
2.ファイル名を指定して実行のチューニング
IDEAツールは、すぐにSQL効率を探してXRebelは、低すぎる推奨しました
テスト
命令:
テーブル名から拡張選択*を説明します。
警告を表示します。
使用説明書には、最適化を行うことを目標とすることができ、文を選択する私たちを助けることができる拡張分析を説明する説明します。
あなたは私たちはそれが最適化された方法にSQLを記述見ることができるの警告を表示し、それは視覚的に優れた独自のSQLかどうかを見つけることができます。
ここでは、テストテーブルには、次のとおりです。
CREATE TABLEを`t_stu`(
` id` INT(11)NOT NULL AUTO_INCREMENT、
`NAME` VARCHAR(20)DEFAULTのNULL、
PRIMARY KEY(` id`)
)ENGINE = InnoDBのAUTO_INCREMENT = 4 DEFAULT CHARSET = UTF8。
コマンド入力は、拡張XXXの説明である結果:
警告を示し;として命令の結果2:
結果は、2つの非常に明確な我々の書き込みSQLが自動的に全体の列名を埋める見ることができます
解決
だから、どのようにそれの結果を分析するには?
結果の要約:(これは、上述したボーエンからの引用です)
彼らは簡単に誤解可能性があり、いくつかのヒントを思い付きました:
-
一般的に、列はNULL NOT NULLがどのように多くの助けのパフォーマンスは変更されませんが、あなたは列に索引を作成する場合、列はNOT NULLに設定する必要がありますすることができます。
-
ない卵と、そのようなINT(11)のように幅整数型を指定します。INT記憶空間の32ビット(4バイト)、それは、INTの範囲を示すことが決定されている(図1)、及びINT(20)が同じのために計算されて記憶されます。
-
UNSIGNEDが負を発現させ、概ね正の数の上限が倍増しました。TINYINTような記憶は、-128〜127の範囲であり、範囲は、UNSIGNED TINYINT 0格納されている - 255。
-
一般的に言って、 DECIMALデータ型を使用する多くの必要はありません。あなたは、財務データを保存する必要がある場合でも、あなたはまだBIGINTを使用することができます。百万分精密部品に必要など、そのデータは、一万人を乗じ、次いでBIGINTストレージを使用することができます。これは、浮動小数点演算がDECIMAL費用のかかる問題の精密かつ正確な計算ではありません回避します。
-
TIMESTAMPは、ストレージ空間の4つのバイトを使用し、DATETIME 8は、記憶空間のバイト。したがって、TIMESTAMPは、範囲が示されDATETIMEよりもはるかに小さい、1970--2038年発現、および、異なるタイムゾーンと異なるのTIMESTAMP値ことができます。
-
ほとんどのケースで使用されていない列挙型は、文字列の欠点列挙リストを追加した場合にのみ削除文字列(列挙型オプションが)ただ、追加要素のリストの末尾に(ALTER TABLEを使用する必要があり、固定されており、必要です)テーブルを再構築する必要はありません。
-
スキーマの列ではありませんあまりにも。理由は、サーバ層が列にバッファの内容を復号、ラインバッファエンジンコピーフォーマットデータストレージエンジンAPIの動作によりサーバ層と記憶層との間に必要とされ、この変換プロセスのコストは非常に高いです。あまりにも多くの列と、いくつかの列が実際に使用した場合、それが高いCPUを引き起こす可能性があります。
-
大きなテーブルALTER TABLEは、MySQLの行いの結果テーブルの変更操作のほとんどは、空のテーブルのシートで新しい構造を作成し、新しいテーブルに古いテーブルからすべてのデータを見つける、その後、古いテーブルを削除するには非常に時間がかかるです。特に、メモリやテーブルはとても大きいですが、それでも多くの指標のがある場合には、それは時間がかかります。もちろん、いくつかの巧妙なのがありますが、この問題を解決することができます役に立たない、自分自身を見ることができます興味を持っています。
インデックスの基礎
バックテーブルに:InnoDBのクエリは第2のインデックスであり、B +ツリーのリーフノードは全データ(インデックスキーと主キーを格納されたInnoDBの2枚の葉のみインデックスキー)が見つかりません、主キーインデックスは+さらにBを得るために再度行くために木を見つけ、これはバックテーブルにあります。
インデックス被覆:上記と同じように、しかし例外は、クエリ列が時間を見つけるためにのみ二次インデックスフィールド、セカンダリインデックスのB +ツリー内の指標であるため、リーフノードは、バックテーブルに所望のデータを有し、且つない、XXから二次インデックスフィールドを選択しています。
インデックスを使用するかどうかmysqlのは、コストベース・オプティマイザは、メイン基盤を決定します。ルールのいくつかのダイセットはラインではありませんので、インテリジェント比較。
例えば、クエリバンドはしないで、等しくありません。多くの人々は、必ずしも必要ではないが、インデックスは失敗につながると言います。
例えば、インクリメントプライマリキーテーブルを想定し、テーブルから選択*どこのid = 1 ;!指数は行くだろう、オプティマイザはこのケースを見つけるために、リーフノードが順序付けられているので、リーフノードID = 1を、見つけます、それは柔軟裁判官なるのがベストですのでので、上がるための指標である、1の後にデータに直接リーフノードを見つけます。