2

テーブル定義、UNIQUEインデックスに注意してください:

CREATE TABLE meta
(
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  type SET('tag', 'keyword') NOT NULL,
  name VARCHAR(255) NOT NULL,
  user_id INT UNSIGNED NOT NULL,
  UNIQUE (name, type, user_id),
  FOREIGN KEY (user_id) REFERENCES user (id) ON DELETE CASCADE
);

そのため、MySQL は検索でインデックスを使用する必要がありますWHERE name = 'tag' and type = 'cat'(左端のプレフィックス) と同様に検索しますWHERE type = 'tag'

やった:

EXPLAIN SELECT * FROM meta WHERE type = 'tag'

結果は次のとおりです (5 列目はpossible_keys):

'1', 'SIMPLE', 'meta', 'ALL', NULL, NULL, NULL, NULL, '1', 'Using where'

私は何かが欠けていると確信していますが、何が見つかりません。どんな手掛かり?

4

2 に答える 2

9

この種の説明はおそらくすでに何度も存在します...しかし、データベースエンジンが説明された状況で通常インデックスを使用しない理由を説明しようとして(WHERE句に複数列インデックスの2番目のフィールドしかない場合)、簡単な類推が役立つかもしれません。

物理的な電話帳 (昔ながらの紙で作られたものの 1 つ) は、インデックスの一種と考えることができます。インデックス キーは名前で、データは電話番号です。電話帳インデックスは、基本的に " Lastname, Firstname" という形式です。電話帳で名前 (Mark Wilkins など) を検索する場合、「Wilkins,Mark」というキーを探していることになります。姓で簡単に名前を検索して、特定の姓のすべてのエントリを見つけることもできます。

しかし、Firstname電話帳の「インデックス」で検索するのは、そう簡単ではありません。で電話帳のすべてのエントリを検索するには、電話帳Firstname=Mark全体をスキャンする必要があります。標準のインデックス (たとえば、b ツリーのようなもの) では、データベース エンジンにまったく同じ問題があります。WHERE 句に 2 列インデックスの 2 番目の列のみが含まれている場合、一致を見つけるにはインデックス全体をスキャンする必要があります。一部のデータベース エンジンは依然としてそれを行う可能性がありますが、通常は結果セットのためにテーブル内のデータを読み取る必要があるため、単純にテーブル自体をスキャンする方が高速な場合があります。

于 2012-08-20T15:28:15.450 に答える
2

このトピックは、すでに別の質問で取り上げられています。

SELECT定義した UNIQUE インデックスをステートメントで使用する場合はtype、インデックス ( ) の最初のフィールドにする必要がありますUNIQUE(type, name, user_id)

MySQL がインデックス複数列インデックスを使用する方法を参照してください。

于 2012-08-20T14:39:09.397 に答える