web-dev-qa-db-ja.com

MySQLテーブルにインデックスを追加する方法

私は約150,000行のデータを持つ非常に大きなMySQLテーブルを持っています。現在、私が試してみると

SELECT * FROM table WHERE id = '1';

iDフィールドがプライマリインデックスであるため、コードは正常に実行されます。しかし、最近プロジェクトの開発のために、私は別の分野でデータベースを検索しなければなりません。例えば

SELECT * FROM table WHERE product_id = '1';

このフィールドは以前はインデックス化されていませんでしたが、インデックスとして追加しましたが、上記のクエリを実行しようとすると結果が非常に遅くなります。 EXPLAINクエリを使用すると、product_idフィールドにインデックスを追加したときにインデックスがないことがわかります。その結果、クエリで単一行を返すのに20分から30分かかります。

私の完全な説明の結果は次のとおりです。

| id | select_type | table | type | possible_keys        | key  | key_len | ref  | rows      | Extra       |
+----+-------------+-------+------+----------------------+------+---------+------+------+------------------+
|  1 | SIMPLE      | table | ALL  | NULL                 | NULL | NULL    | NULL |    157211 | Using where |
+----+-------------+-------+------+----------------------+------+---------+------+------+------------------+

見てみると、IDフィールドはINTとして格納されていますが、PRODUCT_IDフィールドはVARCHARとして格納されています。これが問題の原因となっていませんか?

372
Michael
ALTER TABLE `table` ADD INDEX `product_id` (`product_id`)

MySQLのintegerstringsを決して比較しないでください。 idintの場合は、引用符を削除してください。

558
zerkms
ALTER TABLE TABLE_NAME ADD INDEX (COLUMN_NAME);
142
pabloferraz

この構文を使用してインデックスを追加し、インデックスの種類(HASHまたはBTREE)を制御できます。

create index your_index_name on your_table_name(your_column_name) using HASH;
or
create index your_index_name on your_table_name(your_column_name) using BTREE;

BTREEインデックスとHASHインデックスの違いについては、こちらをご覧ください。 http://dev.mysql.com/doc/refman/5.5/en/index-btree-hash.html

71
Hieu Vo

複数のフィールドインデックスを使用すると、クエリのパフォーマンスが大幅に向上する可能性があります。したがって、上記の例では、ProductIDがルックアップする唯一のフィールドであると想定していますが、ProductID = 1 AND Category = 7と言うクエリで、複数列インデックスが役立ちます。これは次のようにして達成されます。

ALTER TABLE `table` ADD INDEX `index_name` (`col1`,`col2`)

さらに、インデックスはクエリフィールドの順序と一致する必要があります。私の拡張例では、インデックスは(ProductID、Category)でなければなりません。

51
Antony

2つのタイプのインデックスを追加することができます。主キーを定義すると、MySQLはデフォルトでそれをインデックスとして扱います。

説明

インデックスとしての主キー

tbl_studentテーブルがあり、student_idを主キーにしたいとします。

ALTER TABLE `tbl_student` ADD PRIMARY KEY (`student_id`)

上記のステートメントは主キーを追加します。つまり、インデックス付きの値は一意でなければならず、NULLにはできません。

インデックス名を指定します

ALTER TABLE `tbl_student` ADD INDEX student_index (`student_id`)

上記のステートメントはstudent_indexという名前の通常のインデックスを作成します。

一意のインデックスを作成します

ALTER TABLE `tbl_student` ADD UNIQUE student_unique_index (`student_id`)

ここで、student_unique_indexはstudent_idに割り当てられたインデックス名で、値が一意である必要があるインデックスを作成します(ここではnullを受け入れることができます)。

フルテキストオプション

ALTER TABLE `tbl_student` ADD FULLTEXT student_fulltext_index (`student_id`)

上記のステートメントは、student_fulltext_indexでフルテキストインデックス名を作成します。これにはMyISAM Mysqlエンジンが必要です。

インデックスを削除する方法?

DROP INDEX `student_index` ON `tbl_student`

利用可能なインデックスを確認するにはどうすればいいですか?

SHOW INDEX FROM `tbl_student`
44
Jazzzzzz

あなたはあなたがインデックスを持っていると言い、説明はそうではありません。しかし、実際にそうするなら、これはどのように続けるかです:

カラムにインデックスがあり、MySQLがそれを使用しないことを決定した場合、それは以下の理由による可能性があります。

  1. MySQLには、使用に適していると思われる別のインデックスがありますが、使用できるインデックスは1つだけです。通常の検索方法が複数の列の値によるものである場合、解決策は通常複数の列にわたるインデックスです。
  2. MySQLは、一致する行が多数あると判断し、テーブルスキャンの方がおそらく速いと考えています。そうでない場合は、ANALYZE TABLEが役に立ちます。
  3. より複雑なクエリでは、何らかの理由で現在の要件に合わないという、非常に賢い考え抜かれた問題プランに基づいてそれを使用しないことを決定します。

(2)または(3)の場合、 index hint sytax でインデックスを使用するようにMySQLを調整できますが、実際にインデックスを使用することでパフォーマンスが向上するかどうかを判断するために必ずテストを実行します。あなたがそれをほのめかすように。

16
Wrikken