簡単な例から始めましょう。
CREATE TABLE `test` (
`id` INT UNSIGNED NOT NULL,
`value` CHAR(12) NOT NULL,
INDEX (`id`),
INDEX (`value`)
) ENGINE = InnoDB;
したがって、2 つの列で、両方ともインデックスが作成されます。これは、すべてのデータがインデックスに格納されているため、MySQL が実際のテーブルを読み取る必要がなくなることを意味していると思いました。
mysql> EXPLAIN SELECT id FROM test WHERE id = 1;
+----+-------------+-------+------+---------------+------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+-------+------+-------------+
| 1 | SIMPLE | test | ref | id | id | 4 | const | 1 | Using index |
+----+-------------+-------+------+---------------+------+---------+-------+------+-------------+
「インデックスの使用」、とてもいいです。私の理解では、これは、実際のテーブルからではなく、インデックスからデータを読み取っていることを意味します。しかし、私が本当に欲しいのは「値」列です。
mysql> EXPLAIN SELECT value FROM test WHERE id = 1;
+----+-------------+-------+------+---------------+------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+-------+------+-------+
| 1 | SIMPLE | test | ref | id | id | 4 | const | 1 | |
+----+-------------+-------+------+---------------+------+---------+-------+------+-------+
うーん、今回は「インデックスを使用」はありません。
両方の列をカバーするインデックスを追加すると役立つと思いました。
ALTER TABLE `test` ADD INDEX `id_value` (`id`,`value`);
ここで、前の選択ステートメントをもう一度実行して、新しいインデックスを使用するように指示しましょう。
mysql> EXPLAIN SELECT id, value FROM test USE INDEX (id_value) WHERE id = 1;
+----+-------------+-------+------+---------------+----------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+----------+---------+-------+------+-------------+
| 1 | SIMPLE | test | ref | id_value | id_value | 4 | const | 1 | Using index |
+----+-------------+-------+------+---------------+----------+---------+-------+------+-------------+
主をたたえよ、それは索引から読んでいる。
しかし、実際には、他の目的のために複合インデックスは必要ありません。MySQL を 2 つの別々のインデックスから読み取らせることは可能ですか?
どんな洞察も大歓迎です。
編集:わかりました、さらに別の例です。これは、元のテーブル定義 (つまり、各列のインデックス) を使用したものです。
mysql> EXPLAIN SELECT t1.value
-> FROM test AS t1
-> INNER JOIN test AS t2
-> ON t1.id <> t2.id AND t1.value = t2.value
-> WHERE t1.id = 1;
+----+-------------+-------+------+---------------+-------+---------+----------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+-------+---------+----------+------+-------------+
| 1 | SIMPLE | t1 | ref | id,value | id | 4 | const | 1 | |
| 1 | SIMPLE | t2 | ref | value | value | 12 | t1.value | 1 | Using where |
+----+-------------+-------+------+---------------+-------+---------+----------+------+-------------+
これは確かに両方のインデックスから読み取る必要があります (結合条件で両方のフィールドが使用されるため) が、それでも実際のレコードからデータを読み取りますよね? インデックスから読み取ったデータを使用しないのはなぜですか? それとも、「インデックスを使用する」とは言わずに、実際にそのデータを使用しますか?
再度、感謝します