MySQLのインデックスベース(1)

使用のMySQLのインデックス

以下は、理論的知識のメモであります:

まず、インデックスは何ですか?
  インデックスを迅速に特定の値を持つそれらのレコードを見つけるために使用され、すべてのMySQLのインデックスは、B-ツリーの形で保存されます。それが見つかったレコードの要件を満たすまで、インデックスがなければ、MySQLは、クエリが実行されたときにテーブル全体に最初のレコードからすべてのレコードをスキャンするために開始する必要があります。テーブル内のレコード数、上位、この操作のコストより。検索条件として、カラムは任意のレコードをスキャンせずに、インデックス、MySQLを作成した場合は速やかに目標の位置に配置されを記録することができます。テーブルには、順次、少なくとも100倍の高速化よりも記録をスキャンしてインデックス化レコードを検索するために、1000本の記録を持っている場合。
  
  私たちは人々という名前のテーブルを作成するとします。
  
  TABLEの人をCREATE(、NOT NULL名CHAR(50)NOT NULLをSMALLINTをpeopleid);
  
  人のテーブルに1000の異なる値に続いて、我々は完全ランダムな名前。次の図は、データファイルの人々のテーブルの小さな部分を示して
  
  任意の特定の順序でリストされていないことが、データファイル名で見ることができます。私たちは、インデックス名列を作成した場合、MySQLはインデックスのname列をソートします:
  
  各インデックスについて、MySQLが内部で実際に記録されたデータファイルの場所保存するために、「ポインタを。」したがって、我々は「マイク」レコードがpeopleidに等しい名検索したい場合は(SQLコマンドは「人々からpeopleidを選択するWHERE名= 『マイク』;」)、MySQLはインデックス名で「マイク」の値を見つけ、その後に直接行くことができますデータファイル内の対応する行は、peopleid正確ライン(999)を返します。このプロセスでは、MySQLは唯一の返される結果の1行を処理することができます。何の指標「名前」欄、MySQLはデータファイル内のすべてのレコードをスキャンすることがない場合は、その1000年の記録!明らかに、レコードの数が少ないが、それはより速くタスクを完了、MySQLが必要に処理しました。
  
  インデックスの第二に、タイプ
  MySQLはインデックスの種類の様々な利用可能です提供しています:
  
  一般的な指標
  で最も基本的なインデックス・タイプであり、それは独自性などを制限するものではありません。通常インデックスは、いくつかの方法で作成することができる。
  そのようなテーブル名(列リスト)のインデックス<インデックス名> CREATEとしてインデックスを作成、
  改変された形態、例えば表tablenameはINDEX [インデックス名](列リスト)を追加ALTER、
  作成します指定されたインデックスは、例えば、表tableName([...]、CREATE TABLE INDEX [ ;インデックス名](列リスト))
  
  一意のインデックス
  ようなインデックスと前「一般的な指標は、」基本的に同じであるが、ある差分を:索引付きの列のすべての値は一意である必要があり、一度だけ発生する可能性があります。一意のインデックスは、いくつかの方法で作成することができる。
  そのようなテーブル名(列リスト)にユニーク・インデックス<インデックス名>を作成すると、インデックスを作成し、
  修飾された形態、例えば表tablenameはUNIQUE [名前索引](列リスト)を追加ALTER ;
  テーブルを作成するときに、そのような([...]、テーブルのテーブル名を作成するよう指定されたインデックス、 UNIQUE [ 名前索引](列リスト));
  
  プライマリ・キー
  主キーは一意のインデックスであるが、それは「PRIMARY KEY」として指定する必要があります。あなたはタイプのAUTO_INCREMENTカラムを使用している場合は、すでに主キークラスの概念に精通しているかもしれません。一般的に指定された主キーテーブルの作成では、例えば、 "([...]表tablenameをCREATE 、PRIMARY KEY( 列リスト));." しかし、我々はまた、例えば、主キーによってテーブルを変更するために添加することができる「PRIMARY KEY(列リスト)を追加表tablenameをALTER ;.」各テーブルには、1つのプライマリキーを持つことができます。
  
  フルテキストインデックス
  開始からMySQLバージョン3.23.23は、フルテキストインデックス作成とフルテキスト検索をサポートします。MySQLでは、インデックス型のFULLTEXTのフルテキストインデックス。フルテキストインデックスは、タイプVARCHARまたはTEXTの列に作成することができます。これは、CREATE TABLEコマンドを使用して作成することができ、また、CREATE INDEXまたはALTER TABLEコマンドを使用して作成することができます。大きなデータセットの場合、ALTER TABLE介して(またはインデックスの作成)高速フルテキストインデックスを持つ空のテーブルにレコードよりフルテキストインデックスを作成するためのコマンド。この記事は、もはやフルテキストインデックス以下の議論に関与していません。詳細については、MySQLのマニュアルを参照してください。
  
  第三に、単一のインデックスとマルチカラムインデックス
  インデックスは個別のインデックスすることができ、それはマルチカラムインデックスすることができます。私たちは具体的な例で、これらの2つのインデックス間の違いを説明しましょう。人々のテーブルを考えてみましょう:
  
  TABLEの人をCREATE(peopleidはAUTO_INCREMENT、姓CHAR(50)NOT NULL、姓CHAR(50)NOT NULL、年齢SMALLINT NOT NULL NOT NULLをSMALLINT、SMALLINTにNOT NULL、PRIMARY KEY(peopleid)をtownid)。
  
  ここで我々のデータは、人々のテーブルに挿入されます。
  
  このデータフラグメントは、人々の「マイクス」の4つの名前を持っている(そのうちの二つの名前サリバンズ、二つの名前McConnells)、そこに2人の年齢が17歳であるだけでなく、ユニークな名前ジョースミス。
  
  このテーブルの主な目的は、対応するpeopleidを返すように指定したユーザ名、姓、年齢に基づいています。たとえば、我々はマイクサリバンの名前を見つける必要があり、17歳のユーザーは、(FIRSTNAME =「人々からSQLコマンドSELECT peopleidをpeopleidマイク」AND姓=「サリバン」AND年齢= 17;)。私たちが行くように、テーブル全体をスキャンするクエリたびMySQLを実行したくないので、ここで考慮すべきインデックスを使用しています。
  
  まず、我々は、ファーストネーム、姓や年齢列として、単一列に索引を作成することを検討することができます。我々は(INDEXのFIRSTNAME(ADD TABLEの人々をALTERインデックスを作成する場合 FIRSTNAME)を;)FIRSTNAMEの列に、MySQLはすぐにその後、「中間結果セット」内でそれらのファーストネーム= 'マイクのレコードをこのインデックスして検索を制限を置く、となります検索は、他の条件を実施した:最初に、それらの姓レコード「サリバン」を除外して、それらの17歳は、レコード等しくない除外することと同じではありません。すべてのレコードが検索条件を満たした場合、MySQLは検索の最終結果を返します。
  
  FIRSTNAME列インデックスの設立以来、スキャンテーブルの完全な実装に比べて、MySQLの効率は多くのことを改善しているが、我々は、レコードの数はまだ遠い現実の必要性を超えてスキャンするためにMySQLをお願いします。我々はFIRSTNAME列のインデックスを削除し、姓や年齢インデックス列を作成しますが、全体的に、インデックス検索効率を作成するかどうか、と思われることができますが、まだどの列が似ています。
  
  検索効率を改善するために、我々は、マルチカラムインデックスの使用を検討する必要があります。あなたは姓とこれら3つの列の年齢マルチカラムインデックスのFIRSTNAMEを、作成した場合、MySQLは一つだけが正しい結果を見つけるために取得することができます!ここでは、このマルチカラムインデックスのSQLコマンドを作成している:
  
  のALTER TABLE人をADDのINDEXのfname_lname_age(FIRSTNAME、姓、年齢);
  
  インデックスファイルがツリー形式をB-に保存されているため、MySQLはすぐに適切なFIRSTNAMEに移動し、右に行くことができますLASTNAME、そして最終的に適切な年齢に。いずれかのレコードのスキャンデータファイル例がない場合、MySQLは正しく検索レコードのターゲットを識別します!
  
  だから、それぞれのファーストネーム、姓、年齢、もし、か効果、3つの列に別のインデックスを作成し、同じのファーストネーム、姓、年齢マルチカラムインデックスを作成しますか?答えはノー、両者は全く異なっていました。我々は、クエリを実行すると、MySQLはインデックスのみを使用することができます。あなたは3つの単一列索引を使用している場合、MySQLは最も制限のインデックスの上限を選択しようとします。しかし、最も制限単一列のインデックス、その限られた容量と確かにはるかに少ないファーストネーム、姓、年齢マルチカラムインデックスよりも3つの列に。
  
  第四に、最も左接頭
  マルチカラムインデックス最も左接頭辞(左端接頭辞)の概念により具現化と呼ばれるもう一つの利点は、。前の例を検討していき、私たちは今、ファーストネームで複数列のインデックスを持って、姓、年齢の欄には、我々はこのインデックスfname_lname_ageを呼び出します。:検索条件は、さまざまな列の場合は、以下の組み合わせである場合には、MySQLはfname_lname_ageインデックス使用する
  
  のFirstName、LastNameの、年齢
  のFirstName、LastNameの
  姓を
  一方理解し、それは同等であり、これらの列(FIRSTNAME)上(FIRSTNAME、LASTNAME)と組み合わせたインデックスは、我々は(FIRSTNAME、姓、年齢)を作成しました。このfname_lname_ageインデックスを使用することができます次のクエリでは:
  
  SELECTは、人々からWHERE姓=「マイク」AND姓=「サリバン」AND年齢は= '17をpeopleid「; SELECTは、人々からWHERE姓= peopleid」マイク「AND姓=」サリバンを「; FIRSTNAME =「人々からSELECT peopleidマイク」;次のクエリは、すべてのインデックスを使用することはできません。姓=「サリバン」が人々からSELECT peopleid;年齢= '17「のWHERE人々からpeopleidを選択します。人々からpeopleidを選択WHERE姓= 「サリバン」AND年齢= '17 " ;
  
  第五には、インデックス列を選択し
  、パフォーマンスの最適化プロセスにおいて最も重要なステップの一つにインデックスを作成する列を選択します。列には主に2つの種類があり、インデックスの使用を検討してください:列がWHERE句に表示されますが、句は、結合列に表示されます。次のクエリを見てください:
  
  SELECT年齢##は、インデックスを使用していない
  ファーストネーム= '人々から

  
  このクエリと若干異なる前のクエリが、それでも単純なクエリ。年齢はSELECT部分で参照されているので、MySQLは、カラム選択動作を制限するためにそれを使用することはありません。したがって、このクエリ、インデックス年齢を作成するための列の必要はありません。次は、より複雑な例である:
  
  インデックス使用せずにSELECT people.age、##
  インデックス使用せずtown.name ##
  人LEFT JOINのタウンONから
  people.townid = town.townidインデックス##使用することを検討して
  ファーストネーム=「マイク」とインデックス使用を検討し##
  と姓=「サリバン」が##インデックスの使用を検討し
  
  FIRSTNAMEいるので、前の例と、インデックス2つの列を作成することが必要であるので、WHERE句に表示されますLASTNAME。また、原因townid町の表に、今節に参加するので、私たちはその列のインデックスを作成することを検討する必要があります。
  
  そこで、我々は単に私たちは、各列のインデックスWHERE句がすべきだと思うし、それに現れる句に参加することができますか?だから、ほとんどのではなく、かなり。また、列を比較するために、アカウントにオペレータの種類を取る必要があります。<、<=、=、:MySQLはインデックスにのみ、以下の演算子を使用 >、> =、BETWEEN、IN、 およびLIKEいくつかの時間を。これは、操作が開始時にワイルドカード(%または_)に他方のオペランドの場合ではないLIKEインデックスが指す場合に使用することができます。たとえば、「peopleWHEREファーストネームなどからpeopleidを選択 ; 『ミシガン州の%』」 このクエリは、インデックスを使用しますが、ファーストネームが好きなWHERE「人々からpeopleidを選択 『%の池を』;
  

  今、私たちはインデックス列にいくつかの知識を選択する方法を知っているが、最も効果的であるかを判断することができません。MySQLは、組み込みのSQLを支援するコマンドを提供します

 

、MySQLはテーブルを構築し、フィールドが空でない、デフォルトのフィールド値を設定するようにされて設定されます。

フィールドがNULLする必要があるときに二、MySQLは、テーブルを構築し、デフォルトのフィールド値を設定できるように、デフォルト値はNULLではありません。

3つは、フィールドは、この分野では、外部キーと同等であればMySQLは、テーブルを構築し、インデックスに追加する必要があります。

空でない場合は、デフォルト値が一貫してする必要がある場合フォー、MySQLはテーブルを構築し、それ以外の場合は、正しい屈折率コントラストを関連付けることは不可能である、、、異なるテーブル、列の型、長さのタイプ間で同じプロパティ値をフィールドに入力します。

第五に、SQL文は、表だけのためにインデックスを使用することができ、MySQLを使用します。すべてのフィールドタイプは15まで、複数列のインデックスのプロパティをインデックス付けすることができます。

あなたが複数のインデックスを選択することができれば六は、MySQLは通常最小行、唯一のインデックスインデックスの最高値を見つけるためにインデックスを使用しています。

七、インデックスインデックス(その1、その2、その3)、確立指数に相当(その1)、インデックス(その1、その2)およびインデックス(その1、その2、その3)3つのインデックス。

八、のような構文については、MySQLは唯一、次の形式のインデックスを使用する必要があります。

SELECT * FROM T1 WHERE key_col LIKE 'AB%';

ナインは、文の構文でSELECT COUNT(*)は、より高速な実行効率で文がある状況では、効率が速いSELECT COUNT(COL_NAME)でない状態ではありません。

テン、及び複数の条件が複数のプロパティでなければならない状態では、key_part列インデックスであり、key_part1を含まなければなりません。各単一のインデックス場合は、最低限の行を横断するインデックスを使用します。

条件の各条件における複数の有効なインデックスでなければならない状態に11、。

十二は、条件によってORDERは、一貫したソート順(昇順またはその両方、などが下降される)でなければならない同じインデックス属性の後ろでなければなりません。

サーティーン、列の参照すべてのGROUP BYは、同じインデックス属性、およびインデックスは、そのキーワードを節約するためにする必要があります。

十四は、ONインデックスを、JOINと一致するすべてのフィールドは、適切なインデックスを確立すべきです。

第五に、インデックスより高い効率を使用し、MySQLを知らせるために、FORCE INDEXのスマートスキャンにテーブル全体を使用しています。

XVIは、定期的にキーワードテーブルスキャン分布を更新するために、テーブルtbl_nameを分析します。

文をチェック遅いログのXVII定期的に使用、実行は、インデックスの可能な改善を分析し、説明します。

八、許可条件は、(グローバルパラメータ)のより大きなkey_buffer_sizeはとquery_cache_sizeの値、及びsort_buffer_size(4Mを超えないように推奨されるセッション変数)の値を設定します。

おすすめ

転載: blog.csdn.net/qqyb2000/article/details/83013238