sql >> データベース >  >> RDS >> Mysql

MySQLのパフォーマンス:MySQL/MariaDBインデックス

    MySQL / MariaDBデータベースのデータは、テーブルに保存されます。インデックスについて考える簡単な方法は、広範なスプレッドシートを想像することです。このタイプのシステムは、必ずしも迅速な検索に役立つとは限りません。そこで、インデックスが不可欠になります。インデックスがない場合、データベースエンジンは1行目から開始し、すべての行を参照して対応する値を探す必要があります。これが小さなテーブルであれば、大したことではありませんが、数百万、さらには数十億の行を持つテーブルが存在する可能性がある大きなテーブルやアプリケーションでは、問題が発生します。ご想像のとおり、最新のハードウェアであっても、これらの行を1つずつ検索するには時間がかかります。解決策は、データのINDEX(または複数)を作成することです。

    インデックスとは何ですか?

    インデックスは、データベース内でデータを取得できる場所へのポインタを含む、整理されたルックアップテーブルです。この概念は、本の索引に似ています。本の中で、索引はさまざまなトピックが配置されているページ番号をリストします。データベースでは、インデックスは論理的でソートされた順序でポインタを格納し、データベースでの迅速なルックアップを可能にします。インデックスのない本を想像してみてください。特定のトピックに関する情報を検索する場合は、最初から始めて、探している情報が見つかるまでページをめくる必要があります。本の索引は、あなたが探している情報がどのページであるかを正確に伝えることによってこれを解決します。これは基本的にMySQLインデックスの仕組みです。

    MySQLはいつインデックスを使用しますか?

    データベースサーバーが情報を検索する必要があるときはいつでも、インデックスを使用してプロセスを高速化します。この例には、WHERE、JOIN ON、MIN / MAX、およびORDER BY /GROUPBY句が含まれます。これらの状況のいずれかでクエリが列を頻繁に検索または照合する場合は、インデックスの作成を検討する必要があります。

    インデックスはデータベースのパフォーマンスを向上させますか?

    ほとんどの場合、簡単な答えは「はい」です。データの読み取りと検索の場合、インデックスはパフォーマンスを完全に向上させます。全表スキャンを実行しないと、ほぼすべてのSELECTクエリが改善されます。これは少額です。頻繁に操作される列の場合、変更ごとにコストがかかります。これにより、データベースのINSERTとUPDATEが停止する可能性があります。

    一般的なMySQLインデックスタイプ

    MySQLインデックスには次の3つの一般的なタイプがあります。

    • 主キー
    • インデックス
    • ユニーク

    主キー

    主キーは、テーブル内で最も重要な列であるデータベースサーバーに通知します。通常、これはauto_incrementid列に使用されます。たとえば、従業員情報を含むテーブルがある場合、「EMPLOYEE_ID」列に主キーが必要になります。他のテーブル、つまり給与テーブルでは、従業員のすべてのデータではなく、単にEMPLOYEE_IDを参照します。

    インデックス

    標準のINDEXは、テーブル内の1つ以上の列が大量に検索されることをデータベースサーバーに通知するために使用されます。したがって、それらの列にインデックスを作成する必要があります。これは、テーブルの作成中に作成することも、後で列にインデックスが必要になった場合に追加することもできます。

    ユニーク

    UNIQUEインデックスは、テーブルに書き込むことができるものに特定の制約を課すという点で少し異なります。データにすでに含まれている値を含む行を挿入しようとすると、INSERTはエラーを生成します。これにより、迅速な検索とデータの整合性が可能になります。

    インデックスの作成方法

    列にインデックスを作成する方法は複数あります。 CREATE TABLEを実行するとき、または後でALTERTABLEステートメントまたはCREATEINDEXステートメントを使用してインデックスを設定できます。

    主キーインデックスの作成

    PRIMARY KEYインデックスを作成する最も簡単な方法は、テーブルを作成するときに作成することです。このチュートリアルでは、employeeテーブルの例を使用します。テーブルには、ID、FIRSTNAME、およびLASTNAMEの3つの列があります。作成は次のようになります:

    CREATE TABLE EMPLOYEE
    (
      ID INT,
      FIRSTNAME CHAR(32),
      LASTNAME CHAR(32)
    );

    このステートメントは、インデックスなしでテーブルを作成します。次のようなステートメントで主キーを追加できます:

    ALTER TABLE EMPLOYEE
      ADD CONSTRAINT PRIMARY KEY (ID);

    これにより、MySQLに列IDに主キーがあることが通知されます。

    これを行うためのより簡単な方法は、テーブルの作成中です。最初からやり直して、テーブルを再作成し、1つのステートメントに主キーを追加します。

    CREATE TABLE EMPLOYEE
    (
      ID INT,
      FIRSTNAME CHAR(32),
      LASTNAME CHAR(32),
      PRIMARY KEY (ID)
    );

    この単一のステートメントは、上記の最初の2つのステートメントと同じタスクを実行します。主キーには複数の列を含めることができますが、列はすべて一意である必要があります。主キーは、テーブル内の個々の行を識別するために使用できます。

    CREATEINDEXを使用したインデックスの作成

    上記の表の例を使用して、会社に数千人の従業員がいて、名前で従業員をすばやく検索できるようにしたいとします。主キーの場合、エントリは1つだけです。同じ従業員IDを持つ複数の人を含めることはできません。姓の場合、複数の人がその名前を共有することは非常に一般的です。繰り返しますが、これを行うにはいくつかの方法があります。上記の表を使用する:

    CREATE TABLE EMPLOYEE
    (
      ID INT,
      FIRSTNAME CHAR(32),
      LASTNAME CHAR(32),
      PRIMARY KEY (ID)
    );

    次のように、列LASTNAMEにインデックスを追加できます。

    CREATE INDEX idx1 ON EMPLOYEE (LASTNAME);

    LASTNAMEによる検索は、このテーブルでより高速になります。この例では、「idx1」はインデックスの名前です。これにより、必要に応じて、将来的にインデックス自体を参照しやすくなります。

    テーブルにインデックスを追加する別の方法は、ALTERTABLEコマンドを使用することです。前のステートメントで行ったのと同じことを実行するには、次のコマンドを実行します。

    ALTER TABLE EMPLOYEE ADD INDEX idx1 (LASTNAME);

    時間を節約するインデックスを追加する最後の方法は、CREATETABLE中に追加することです。特定の列を検索または結合することが事前にわかっている場合は、すでにそこにあるインデックスを使用して初期テーブルを作成できます。

    CREATE TABLE EMPLOYEE
    (
      ID INT,
      FIRSTNAME CHAR(32),
      LASTNAME CHAR(32),
      PRIMARY KEY (ID),
      INDEX idx1 (LASTNAME)
    );

    これらの3つのステートメントはすべて、同じ結果を作成します。

    複数列のインデックス

    インデックスは単一の列にある必要はありません。 FIRSTNAMEとLASTNAMEの両方でより高速なルックアップが必要な場合は、両方の列にインデックスを作成できます。テーブルの作成では、次のようになります。

    CREATE TABLE EMPLOYEE
    (
      ID INT,
      FIRSTNAME CHAR(32),
      LASTNAME CHAR(32),
      PRIMARY KEY (ID),
      INDEX idx2 (LASTNAME,FIRSTNAME)
    );

    CREATE INDEXコマンドの使用:

    CREATE INDEX idx2 ON EMPLOYEE (LASTNAME, FIRSTNAME);

    そして最後に、ALTER TABLEコマンド:

    ALTER TABLE EMPLOYEE ADD INDEX idx2 (LASTNAME, FIRSTNAME);

    一意のインデックスの作成

    列にインデックスを作成し、その列のすべてのエントリを強制的に一意にしたい場合があります。サンプルテーブルを拡張してOFFICE列(建物内のどのオフィスがあるかを示す)を含める場合は、これをUNIQUEインデックスにすることができます。このテーブルを使ってみましょう:

    CREATE TABLE EMPLOYEE
    (
      ID INT,
      FIRSTNAME CHAR(32),
      LASTNAME CHAR(32),
      OFFICE INT,
      PRIMARY KEY (ID)
    );

    これで、その人がどのオフィスを占有しているかを示す整数がテーブルに格納されていることに注意してください。これは、建物内のさまざまなオフィスに関する情報が含まれる別のテーブル「OFFICES」を参照している場合があります。

    これにインデックスを作成するには、次のコマンドを発行します。

    CREATE UNIQUE INDEX idx3 ON EMPLOYEE (OFFICE);

    同様のコマンドを使用して、CREATETABLEコマンドとALTERTABLEコマンドでこれらを作成できます。ここで、これら2つの挿入を実行しようとした場合:

    INSERT INTO EMPLOYEE (ID, FIRSTNAME, LASTNAME, OFFICE) VALUES (1, 'JANE', 'JOHNSON', 1);
    
    INSERT INTO EMPLOYEE (ID, FIRSTNAME, LASTNAME, OFFICE) VALUES (2, 'JOHN', 'SMITH', 1);

    2番目のINSERTでエラーが発生します:

    Duplicate entry '1' for key 'idx3'

    インデックスの削除

    列のインデックスが不要になるときが来るかもしれません。おそらく、列をそれほど頻繁に検索しておらず、インデックスによって挿入と更新が遅くなっていることに気付いたかもしれません。これを行うには、DROPINDEXコマンドを使用します。テーブルは次のように作成されました:

    CREATE TABLE EMPLOYEE
    (
      ID INT,
      FIRSTNAME CHAR,
      LASTNAME CHAR,
      PRIMARY KEY (ID),
      INDEX idx (LASTNAME,FIRSTNAME)
    );

    LASTNAME列とFIRSTNAME列のインデックスを削除する場合は、次のコマンドを発行します。

    DROP INDEX IDX ON EMPLOYEE;

    結論

    データベースインデックスは、テーブル内の検索と読み取りのパフォーマンスを利用する構造内のデータ取得の速度を最適化する基本的なツールです。インデックスの拡張は、最適なインデックスデータ構造を維持するために、主に書き込みやストレージスペースの増加を犠牲にして推進されます。

    MySQLおよびMariaDBデータベースは、ここで取り上げられていない多くのものを含め、他の複数の検索および読み取りオプションを提供します。ここでの重要なポイントは次のとおりです。

    • 事前にテーブルの計画を立てる時間を取ってください。
    • テーブルを作成するときに事前に計画を立てていない場合は、最も検索されている列を評価し、それらのインデックスを作成します。

    実際の動作をご覧ください!

    当社の専用サーバーの幅広いラインアップは、成長するビジネスから最大規模の企業向けの高可用性クラスターサーバーセットアップまで、最小のデータベースをホストするために必要なパワー、安定性、およびセキュリティを提供します。お客様のニーズを満たすために当社が提供できるソリューションをご覧になりたいですか?

    800.580.4985までお電話いただくか、チャットまたはチケットを開いて、知識豊富なソリューションまたは経験豊富なホスティングアドバイザーのいずれかと話し、このテクノロジーを今日活用する方法を学びましょう。

    シリーズナビゲーション<<前の記事次の記事>>

    1. 修正:Oracleデータベースの「間隔の主要な精度が小さすぎる」

    2. 前月のすべての日付を一覧表示するoraclesqlクエリ

    3. 式インデックスの有用性について

    4. Oracle SQL*Plusの使用方法