MySQL
インデックスとキー
サーチ…
構文
- 単純なインデックスを作成する
CREATE INDEX index_name ON table_name ( column_name1 [、 column_name2 、...])
- ユニークなインデックスを作成する
table_nameでUNIQUE INDEXをindex_nameのを CREATE(column_name1 [、column_name2、...]
- ドロップインデックス
DROP INDEX index_name ON tbl_name [ アルゴリズム _オプション | lock_option ] ...
algorithm_option:アルゴリズム [=] {DEFAULT | INPLACE | COPY}
lock_option: LOCK [=] {DEFAULT | NONE | SHARED | EXCLUSIVE}
備考
コンセプト
MySQLテーブルのインデックスはブックのインデックスのように機能します。
たとえば、データベースに関する書籍があり、ストレージなどの情報を探したいとします。索引がなければ(目次のような他の援助がないと仮定して)、トピックを見つけられるまで(それは「全表スキャン」)、ページを1つずつ調べなければなりません。一方、索引にはキーワードのリストがあるので、索引を参照して、その記憶域が113-120,231、および354ページに記載されていることを確認します。次に、検索せずに直接それらのページに移動できますインデックス付きの検索、やや速い)。
もちろん、インデックスの有用性は多くの事柄に依存します - いくつかの例では、上のsimileを使用します:
- あなたがデータベースに関する本を持っていて、 "データベース"という言葉を索引付けしている場合は、1-59ページ、61-290ページ、および292-400ページに記載されていることがあります。それは多くのページであり、そのような場合、インデックスはそれほど役立つものではなく、ページを順番に調べるほうが速いかもしれません。 (データベースでは、これは「選択性の悪さ」です。)
- 10ページの本については、5ページのインデックスがプレフィックスされた10ページの書籍で終わる可能性があるため、インデックスを作成するのは意味がありません。ちょうど愚かです。10ページをスキャンして完了します。
- また、インデックスは有用である必要があります。たとえば、ページあたりの文字数「L」の頻度など、一般的にインデックスを作成する必要はありません。
インデックスを作成する
-- Create an index for column 'name' in table 'my_table'
CREATE INDEX idx_name ON my_table(name);
ユニークなインデックスを作成する
ユニークなインデックスは、重複したデータをテーブルに挿入することを防ぎます。一意索引の一部を形成する列にNULL
値を挿入することができます(定義上、 NULL
値は別のNULL
値を含む他の値とは異なるため)
-- Creates a unique index for column 'name' in table 'my_table'
CREATE UNIQUE INDEX idx_name ON my_table(name);
ドロップインデックス
-- Drop an index for column 'name' in table 'my_table'
DROP INDEX idx_name ON my_table;
複合インデックスを作成する
これにより、両方のキー( mystring
およびmydatetime
複合インデックスが作成され、 WHERE
句の両方のカラムでクエリが高速化されます。
CREATE INDEX idx_mycol_myothercol ON my_table(mycol, myothercol)
注:順序は重要です!検索クエリにWHERE
句の両方の列が含まれていない場合は、最も左のインデックスのみを使用できます。この場合、クエリとmycol
でWHERE
、インデックス、探しクエリを使用しますmyothercol
も探しなし mycol
ませんが。詳細については、 このブログ記事をご覧ください 。
注: BTREEの動作のため、通常は範囲で照会される列は最も右の値になります。たとえば、 DATETIME
カラムは、 WHERE datecol > '2016-01-01 00:00:00'
ように通常は照会されWHERE datecol > '2016-01-01 00:00:00'
。 BTREEインデックスは範囲を非常に効率的に処理しますが、範囲としてクエリされた列が複合インデックスの最後のインデックスである場合に限ります。
AUTO_INCREMENTキー
CREATE TABLE (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
...
PRIMARY KEY(id),
... );
メインノート:
- 1から始まり、
INSERT
に指定しなかった場合は自動的に1ずつインクリメントするか、NULL
として指定しNULL
。 - IDは常に互いに区別されますが...
- 特定の瞬間に一意ではなく、idの値についての何らかの前提(ギャップがなく、連続的に生成され、再使用されないなど)をしないでください。
微妙なノート:
- サーバーの再起動時に、 '次の'値は
MAX(id)+1
として '計算されます'。 - シャットダウンまたはクラッシュ前の最後の操作が最高のIDを削除する場合は 、そのID を再利用できます(これはエンジンに依存します)。だから、 auto_incrementsが永久にユニークであると信用しないでください 。彼らはいつでも一意でしかありません。
- マルチマスターソリューションまたはクラスタソリューションについては、
auto_increment_offset
およびauto_increment_increment
参照してください。 -
PRIMARY KEY
として何か他のものを持ち、単純にINDEX(id)
実行することはOKです。 (これは状況によっては最適化です。) -
AUTO_INCREMENT
を「PARTITION
キー」として使用することはめったに有益ではありません。違うことをする。 - さまざまな操作によって値が 「焼き付けられる」ことがあります。
INSERT IGNORE
(dupキーを使用)、REPLACE
(DELETE
+INSERT
)などを使用しないで、値を事前割り振りするときに発生します。ROLLBACK
はIDの隙間のもう一つの原因です。 - レプリケーションでは、IDが昇順でスレーブに到達するのを信頼できません。 IDは連続した順序で割り当てられますが、InnoDBステートメントは
COMMIT
順にスレーブに送信されます。