web-dev-qa-db-ja.com

Mysqlクラスター化インデックスをどのように作成しますか?

クラスター化インデックスがどのように機能するかについてすべて読んでいて、それらが私のアプリにとって有益だと思います。主キーは自動的にクラスター化インデックスになることを理解していますが、非主キー列にクラスター化インデックスを追加するにはどうすればよいですか?

つまりユーザー投稿用のデータストア。各投稿にはIDがありますが、ユーザーIDもありますが、ユーザーは複数回投稿できるため、ユーザーIDは主キーではありません。クラスター化インデックスをユーザーIDにどのように追加しますか?それも良い考えですか?

12
Wiz

クラスター化インデックスとセカンダリインデックス によると、テーブルごとに1つのクラスター化インデックスのみを持つことができます。

クラスタ化インデックス以外のすべてのインデックスは、セカンダリインデックスと呼ばれます。

テーブルにプライマリインデックスがなく、別の一意のインデックスがある場合、これはクラスター化インデックスとして使用されます。

テーブルにPRIMARYKEYを定義しない場合、MySQLはすべてのキー列がNULLではない最初のUNIQUEインデックスを検索し、InnoDBはそれをクラスター化インデックスとして使用します。

したがって、クラスター化インデックスを自分で追加するのではなく、MySQLがクラスター化インデックスとしてテーブルのプライマリインデックスまたは最初の一意のインデックスのいずれかを選択すると結論付けます。

17
Olaf Dietsche

@Olafが説明しているように、InnoDBは、クラスター化インデックス(主キー、または主キーがない場合は最初の一意のインデックス、または2つがない場合は非表示の列)となる列または列の組み合わせを選択します。

クラスター化インデックスとして一意でない列を使用する場合は、post_idを一意のキーとして定義し、user_idpost_idの組み合わせを主キーにすることができます。クラスター化インデックスとして選択:

CREATE TABLE Post
( post_id INT NOT NULL AUTO_INCREMENT
, user_id INT NOT NULL
--- other columns
, CONSTRAINT Post_PK
    PRIMARY KEY (user_id, post_id)     -- your clustered index
, CONSTRAINT post_id_UQ
    UNIQUE (post_id)             -- you still want uniqueness for the `post_id`
) ENGINE = InnoDB ;

これが良い考えであるかどうかは、アプリケーション、データ量、およびクエリによって異なります。一般に、クラスター化されたキーの最良のプロパティは、一意で、狭く、静的で、増え続けることです。そのため、自動インクリメント列が最適です。 Kimberly L. Trippのブログ記事でそれについて読んでください: ますます増加するクラスタリングキー-クラスター化インデックスの議論..........再び! および クラスター化インデックスの議論は続く... (SQL-Server用であるため、停止しないでください。同じ問題がInnoDBのクラスター化インデックスに99%適用されます)

(user_id, post_id)のようなクラスター化されたキーには最初の3つのプロパティがありますが、増え続けることはありません。これにより、CIが断片化され、テーブルへの挿入が遅くなる可能性があります。

ただし、必要なデータがクラスター化インデックス内の1つの場所で必要な順序で見つかるため、WHERE user_id = ?条件または範囲条件WHERE user_id BETWEEN ? AND ?またはGROUP BY user_idグループを持つより効率的なクエリが得られます。 。

私はあなたがあなたのケースに最適なものを選択するためにテストを行うことをお勧めします。


テーブルに複数のクラスター化インデックスを許可するMySQLのバリアントであるTokuDBもあります。彼らの記事の詳細:複数のクラスタリングインデックスの紹介

9
ypercubeᵀᴹ

間違った質問をしていることをお勧めします。

別の質問の1つは、「現在のPRIMARY KEYを削除して、この他のものを「クラスター化」できるようにすることはできますか?」です。多くの場合、AUTO_INCREMENTは削除するか、単純なINDEXに変えることができます。

より可能性の高い質問は、「このSELECT ...の最適なインデックスは何ですか?」です。 secondクラスター化インデックスは基本的なMySQLの問題外であると指摘する人もいますが、次の選択肢は何ですか? SELECTを知らなければ答えられません。ただし、 my Index CookbookSELECTsの大きなレットの質問に答えます。

1
Rick James

InnoDBテーブルに主キーを定義すると、MySQLは主キーをクラスター化インデックスとして使用します。

テーブルの主キーがない場合、MySQLは最初のNIQUEインデックスを検索します。ここで、すべてのキー列はNULLではなく、このUNIQUEインデックスをクラスター化インデックスとして使用します。

InnoDBテーブルに主キーまたは適切なUNIQUEインデックスがない場合、MySQLは、行ID値を含む合成列にGEN_CLUST_INDEXという名前の非表示のクラスター化インデックスを内部的に生成します。

0
Gauravk