インデックスとは何ですか?インデックスでmysqlのクエリを最適化する方法

1.インデックス

      単一のMySQLテーブルは数が多すぎる記録した場合、CRUDのパフォーマンスが急激な減少になります。効率的な操作は非常に重要であるためMySQLのMySQLのインデックスを構築し、指数は大幅のMySQLの検索速度を向上させることができます。単一テーブルのデータは常に将来的に上昇し続ける場合を除き、分割を考慮して起動していない、分割が複雑なのロジック、展開、運用、保守をもたらすでしょう。千万以下で一般的に整数ベースのテーブルには、以下の500万の文字列ベースのテーブルはあまり問題ではありませんし、実際に何度もMySQLはまだ最適化の余地がたくさんある単一のテーブルのパフォーマンス、数千万人をサポートするためのデータの通常の量よりもさらに。


インデックスの長所と短所:

利点:大幅に、サーバーをスキャンする必要があるデータの量を減らし、サーバーがソートや一時テーブルを避けるのを助けることができ、高速検索、ランダムI / Oは、I / Oの回数を減らし、シーケンシャルI / Oとなり、迅速に検索、インデックスのグループ化そしてグループ化し加速することができるソート、ソート。

短所:したがって、インデックステーブル自体、とは、ストレージスペースを取る一般的に、占有インデックステーブルスペースの1.5倍のデータテーブルは、維持し、インデックステーブルを作成するには、時間、コスト、データの量とコスト上昇を取ります;インデックスを作成するときにテーブルをロックする必要があるので、実際の業務はアイドルする必要があります。また、データテーブルを変更すると同時に、インデックステーブルを変更する必要があるため、インデックスは、データテーブルの変更操作(削除、追加、変更)の効率を、削減する建設中。


2.インデックスのタイプ

      MySQLの存在は、いくつかのインデックス・タイプがあります。FULLTEXT、HASH、BTREE、RTREE。

FULLTEXT

      これは、フルテキストインデックス、専用MyISAMエンジンのサポートです。これは、INDEXの使用をCREATE、ALTER TABLEを、CREATE TABLEをすることができますが、今だけCHAR、VARCHAR、TEXT列のフルテキストインデックスを作成することができます。

      MyISAMテーブルとフルテキストインデックスが一緒に生まれていない、「%の単語%」問題名LIKEのテキストのあいまい検索のこのタイプの低効率を解決するために表示されます。
FULLTEXT(全文)インデックスは、MyISAMテーブルとInnoDBのためにのみ利用可能です

  • 大きなデータセットの場合、無FULLTEXTインデックステーブルにデータを追加する、および添加速度は、より高速なデータが追加されるよりFULLTEXTインデックステーブルFULLTEXTインデックスを有します。

  • MySQLのエンジンは、他のデータであれば、以前の5.6バージョンのフルテキストインデックスのみ、MyISAMストレージエンジンを使用することができますが付属して、その後、フルテキストインデックスは有効になりません。InnoDBストレージエンジンの5.6バージョンでは、フルテキストインデックスをサポートするために始めました

  • MySQLでは、フルテキストインデックスの離脱英語は現在の中国はまだサポートされていない、便利です。NGRAMを使用して、プラグインの5.7バージョンの後、中国をサポートするために始めました。

  • 文字列が取得できない、所望の結果を取得するには短すぎる場合、検索文字がストップワードが含まれている場合MySQLでは、少なくとも4バイトの検索文字列の長さはまた、ストップワードは無視されます。

ハッシュ

      ハッシュアルゴリズムを使用し、したがって、非常に高速なアクセスが、値は一つだけに対応するため、記憶された値は、対応する位置のハッシュコードにおけるデータの行の物理的な場所を実行し、索引列の基準値ハッシュコード値を算出したハッシュインデックスハッシュコード、および一方向ハッシュを配布されています。キーと値のペアハッシュの形で(のみほぼ100%)のみ、等ので、指標として適しています。

      HASHインデックスは、層によって層としてtreeインデックスのように見える必要があり、そのため非常に高い効率を持っていない、1を見つけることができます。しかし、この効率は、「=」との問い合わせの範囲のための効果的な条件の下で、発注と組み合わせ指数は依然として非効率的である「で」、つまり、条件付きです。

BTREE

      BTREE(B +ツリーは)、木構造(二分木)に格納されたデータが、たびにクエリが葉を得、ノードを通過する、アクセスルートツリーから開始される特定のアルゴリズムに従ったインデックス値に指標の一種です。BTREE非リーフノードがデータを格納しないので、(データ)、したがって、リーフノードにすべてのデータをチェックする必要があり、すべてのデータのクエリの速度が同じになるように、リーフノードは、同じ高さです。これは、MySQLのデフォルトとインデックスの最も一般的なタイプです。

RTREE

      めったにMySQLの中で使用されていないRTREE、唯一のジオメトリデータ型をサポートし、ストレージエンジンのタイプはMyISAMのみをサポートし、BDB、InnoDBは、NDbの、アーカイブは少数。

      BTREEと比較して、RTREE強度は、検索の範囲にあります。


3.インデックス種

一般的なインデックス:クエリのみをスピードアップ。

唯一のインデックス:ユニークなクエリ列値をスピードアップ+(ヌルが存在することができます)。

主キーのインデックス:クエリ+列(ヌルを持っていない)+ 1つのテーブルのみをスピードアップするための固有の値。

コンポジットインデックス:複数列の値がインデックス、専用の検索を組み合わせて構成し、その効率は、インデックスマージよりも大きい場合、「最も左接頭辞」の原則に従って、最も一般的に検索として使用されるか、または降順で、左端の列に並べ替え、組み合わせ指数はかなりCOL1、col1col2を確立するために、3つのインデックスをcol1col2col3が、COL2またはCOL3は、インデックスを使用することはできません。

フルテキストインデックス:テキストの内容は、単語検索を分けています。


4.ポリシーインデックス


4.1場合は、インデックスを使用するには?

  • 主キーは自動的に一意のインデックスを作成します。
  • WHEREまたはORDERが多いクエリとしてBY;
    列ステートメントは、インデックスを作成することが表示されます。
  • ソート列としてインデックス付けされます。
  • クエリーテーブルやその他の関連分野、外部キー関係インデックス
  • 高い同時併用指数の下傾向。
  • 関数は、例えば、重合列のインデックス、MAX(COLUMN_1)COLUMN_1又はカウント(COLUMN_1)のインデックスを作成する必要があるために使用することができます。


4.2場合は、インデックスを使用しませんか?

  • インデックスの列ではないと頻繁に追加および削除。
  • インデックスが作成されていない重複した列の数が多いがあります。
  • ないインデックスに少なすぎるテーブルのレコード。データベースがすでに十分なテストデータを持っている場合にのみ、そのパフォーマンスの結果は、実用的な基準値を持っています。またはインデックスを使用せずに - テスト用データベースに記録されたデータのわずか数百が、彼らは最初のクエリの完了後に実行する傾向がある場合は、後続のすべてのクエリーコマンドは非常に高速に実行されるようになりますこれは、メモリにロードされました。1000以上のデータベース・レコードは、データの量もMySQLサーバ上のメモリの合計量を超えた場合にのみ、データベースのパフォーマンステストの結果は、意味のあるものにします。


インデックス例4.3失敗:

  • 複合インデックス内のカラムを持つことはできません、その後、複合インデックスのために、この列が無効であるが存在する場合、NULLです。
  • その後で、ORDER BYを使用しない、WHERE句で使用する場合、SELECTステートメントでは、インデックスは一度だけ使用することができます。
  • LIKE操作は、「%のAAA%」はインデックスを使用しない、すなわち、インデックスが失敗しますが、「AAA%」はインデックスを使用することができます。
  • インデックスを使用して、式や関数は、たとえば、列インデックスに失敗します。
select * from table where ceate_time > unix_timestamp(curdate());

これは、完全なテーブルのインデックススキャン中に障害につながる各ライン操作、に行われますので、我々は、パラメータとしてプログラムによって現在の時刻を変更することができます。

select * from table where ceate_time > 1524561911;

その他のワイルドカードと同じ、それは、正規表現でのクエリで使用される条件は、ワイルドカードのみではありません検索テンプレートの最初の文字の場合は、インデックスを使うと言うことです。

  • クエリの条件で使用される<記号>と記号を含め、同じではありません!=インデックスは失敗につながります。特に:あなたは、主キーインデックスを使用している場合は!主キーのインデックス型や整数インデックス<記号または>シンボル・インデックスが障害を起こしていない場合=インデックスは、失敗しません。(<シンボル>シンボルと、全体の非常に小さな割合が記録されている場合を含め、等しくない、それが失敗することはありません!)。
  • 使用して、クエリ内のNULL ISや故障につながる可能性NULLインデックスではありません。
  • 単一引用符文字列は、インデックスが失敗原因となります。障害の種類は、モバイル分野など、不整合が生じることができると言うために、より正確な文字列型で、WHEREモバイル= 99999を使用すると、故障の原因となりますWHEREモバイル=「99999」交換する必要があります。
  • この時点では、クエリ条件を使用するか、インデックスの障害を引き起こす可能性があります複数の条件を接続し、各ORリンクの条件がインデックス化されない限りは、二回のクエリを変更し、すべてのUNIONで接続する必要があります。
  • インデックスを使用して並べ替えフィールドは、そのフィールドは、フィールドをインデックス化する必要があります]を選択した場合、インデックスがそうでない場合は失敗します。特に:ソートがある場合は、主キーインデックスは*は、インデックスの失敗にはなりません選択します。
  • 私たちがしなければならない場合は、複数列のソートを含まないようにしてください、それがこのキューの複合インデックスを構築するのが最善の方法です。


4.4 MySQLのクエリの最適化:

フィールド:

  • 非負プラスUNSIGNED場合、INTとして使用TINYINT、SMALLINT、MEDIUM_INT整数型ではなくを確認します。
  • VARCHAR長分布はだけは本当にスペースを必要とします。
  • 代わりに整数列または列挙型を使用します。
  • 代わりにDATETIMEのTIMESTAMPを使用してみてください。
  • あまりにも多くの単一のテーブルのフィールドを持っていない、それが20以内を推奨します。
  • NULLフィールド、クエリの最適化を使用しないでくださいし、余分なスペースのインデックスを取ることは困難です。
  • 整数でIPを格納します。

インデックス:

  • インデックスがクエリに基づいてターゲットに作成するには、ことはできません、インデックスまたは全表スキャンを見に説明するのに従ってかどうかを使用することができWHEREおよびORDERインデックスを伴うコマンドBYに上場を検討します。
  • フィールドがNULL値に避けるべきであるWHERE句で決定され、エンジンがインデックスとフルテーブルスキャンを使用してあきらめてしまいます。
  • 値の分布は疎フィールドは、「性別」フィールドのみ二つまたは三つの値として、インデックスを構築するには適していないです。
  • 唯一の接頭辞インデックスを構築するための文字フィールド。
  • 文字は、主キーをフィールドすることが最善ではありません。
  • プログラムによって保証されませ外部キー制約ません。
  • 手続きの保証に縛ら、UNIQUEないようにしてください。
  • 思想及びクエリー配列は、複数列のインデックスを使用する場合、不要な単一のインデックスを削除して一貫しています。

クエリSQL:

  • SQLが遅くスロークエリログを開いて見つけるすることができます。
  • 算術列は行わないでください。SELECT ID、年齢+ 1 = 10を、カラム上の任意の操作は、データベースのチュートリアル機能が含まれてテーブルスキャンを引き起こす式を評価、など、クエリとして等号の右側に操作を移動することになります。
  • できるだけ簡単なSQL文:;ロックの時間を短縮することが大きなステートメント解体小さな文; SQLのみCPUの動作に大きなSQLライブラリ全体をブロックすることができます。
  • * SELECTありません。
  • INまたは書き換え:nまたは効率のレベル、効率はログ(n)のレベル、IN 200内で制御提案の数です。
  • 機能やアプリケーションの実装をトリガしないでください。
  • %XXX-スタイルの問い合わせを避けるため、「%のXXX%」は、インデックスを使用していない、あなたは、フルテキストインデックス、およびを使用することができます。
SELECT * FROM tablename MATCH(index_colum) ANGAINST(‘word’);
  • 以下のJOIN;
  • 例えば「123」及び「123」比、123及び123の比と同じタイプを使用して比較しました。
  • ほとんどの複合インデックス接頭辞の原則に従うことを、コラムように左側に並べ替え、およびグループ化を最高周波数。
  • インデックスとフルテーブルスキャン!;を使用して放棄するのか、WHERE句= <>演算子、そうでないエンジンでの使用は避けてください
  • 連続的な値については、IN BETWEEN用いない:1と5の間のT WHERE NUMからIDを選択します。
  • ページ番号が大きすぎない、ページネーションにLIMITを使用するために、データ・テーブルの完全なリストを服用しないでください。
  • 可能ならば、あなたはプレフィックス長を指定する必要があり、短いインデックスを使用してください。例えば、CHAR(255)の列がある場合、フロントのみ多値で10のまたは20文字は、インデックスに列全体をしない場合。ショートインデックスは、検索を高速化し、ディスク容量とI / O操作を保存することはできません。


4.5よくあるご質問インデックス

1、インデックスがしているのですか?

      インデックスは、すぐに行の列で特定の値を見つけるために使用されます。インデックスを使用しないでください、あなたが該当する行を見つけるまで、MySQLは最初のレコードからテーブル全体を読み取るために開始する必要があります。テーブルが大きいほど、より多くの時間はそれがかかります。テーブル、クエリインデックス内の列を持っている場合、mysqlは迅速にデータファイルの真ん中を見つけるための位置に到達することができ、すべてのデータを表示する必要はありません。

      ほとんどのMySQLのインデックス(プライマリ・キー、インデックス、ユニークな、フルテキスト) Bツリーに格納されているが、R-treeインデックスを使用して空間データ型、また、ハッシュインデックステーブルメモリをサポートします。


2、良い指標複合体は、私がどのようにインデックスを理解し、より鮮やかな例がありますか?

      あなたはこの辞書の前に持っていることを想像し、データが書籍のテキストである、あなたは、CPUだ、とインデックスは本のディレクトリです。


3、より良い指標?

      ほとんどの場合、インデックスが大幅にクエリの効率を向上させることができます。しかし:
データの変更(追加、削除)のインデックスを維持するために必要とされるので、複数のインデックスは、より多くのメンテナンスコストを意味し、
また、より多くの制御空間を意味します(ブック100を、50カタログがあるのですか?)。
小さすぎますテーブル、インデックスを構築することは遅くなることがあります(パンフレット2を読んで、あなたが最初のディレクトリに移動する必要がありますか?)


4、インデックスフィールドの種類の問題

      テキストタイプ、インデックスが構築されてもよい(長さを指定する);総合MyISAMストレージエンジンは、1000バイトの長さを超えることができない;スクリーニングおよび索引列同じデータ型の値を保持するために使用されます。


5、インデックスを使用したいですか?

      以下のようなクエリを最小化し、それが「XXX%」は、インデックスで使用することができ、絶対的に利用できないではありません。また同様に、オペレータは、インデックスを使用することができます。

<,<=,=,>,>=,between,in

インデックスよりこれらの小さいです:

<>,not in,!=



6、どのようなフィールドのインデックスを構築するには適していませんか?

      一意列の値は、インデックス付けには適していない、(性別、種類等)が小さすぎます。データのインデックスのために非常に頻繁に更新されていません(どのサイズは?一般的に言って、テーブルの15%以上とのデータの値は、インデックスを構築する必要はありません)。


7、クエリが複数のインデックスを使用することができますか?

      ない


どのようにインデックスを構築するための8、複数列のクエリ?

      クエリは、唯一のインデックス、インデックス付きの列またはインデックス付きの列bを使用することができますか?誰が差別高い(同じ値以下)、内蔵!もちろん、共同指数は良いプログラムです。


9、関節のインデックスを発行

-- 命中col1、col2联合索引
select col1,col2 from test where col1 = 'xxx';
-- 不能命中col1、col2联合索引
select col1,col2 from test where col2 = 'xxx';

だから、ほとんどの場合、そこCOL1、COL2インデックスであり、インデックス付きCOL1を構築するために行くだろう。


10.一般的な状況は、インデックスを使用することはできません何ですか?

like '%xxx'
not in
!=

列には、次のような、計算機能します:

where md5(password) = "xxx"

(電話番号など)は、文字列型のフィールドの値を維持し、クエリは、そうでなければ、インデックスを打つことができない、引用された値を失うことはありません覚えています。

select * from test where mobile = 13800002222;

モバイルフィールドがcharまたはvarchar型の場合上記のクエリがインデックスを打つことができない、次のようになります。

select * from test where mobile = '13800002222';


11、NULL問題

      ヌルインデックスが存在しないにつながるので、デザインのテーブル構造は、NULLの存在下で避けるべきです。
-1のような他の方法を、発現させることができます。

参考:
https://blog.csdn.net/liutong123987/article/details/79384395

https://blog.csdn.net/github_26672553/article/details/82887009

https://blog.csdn.net/tongdanping/article/詳細/ 79878302

おすすめ

転載: www.cnblogs.com/qingfengEthan/p/11329144.html