1
考虑一个表具有以下字段:结合覆盖指数具有唯一约束在MySQL
mysql> DESCRIBE my_table;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| pk | int(11) | NO | PRI | NULL | |
| name | varchar(20) | NO | UNI | | |
| value | varchar(255) | NO | | | |
+-------+--------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
注意字段名称具有唯一约束。
可以说,我想优化以下查询:
SELECT name, value
FROM my_table
WHERE name = 'my_name'
已经存在的name
场(由于独特约束)的索引,但它甚至会更好,有一个覆盖指数为value
。
只需一个指数为唯一约束,没什么好惊讶发生在我运行EXPLAIN
命令:
mysql> EXPLAIN
-> SELECT name, value
-> FROM my_table
-> WHERE name = "my_name";
+----+-------------+----------+-------+---------------+------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+-------+---------------+------+---------+-------+------+-------+
| 1 | SIMPLE | my_table | const | name | name | 62 | const | 1 | |
+----+-------------+----------+-------+---------------+------+---------+-------+------+-------+
现在,如果我尝试添加一个覆盖索引,
ALTER TABLE my_table ADD INDEX idx_name_value (name, value);
显示为查询的候选人,但未被选中!
mysql> EXPLAIN
-> SELECT name, value
-> FROM my_table
-> WHERE name = "my_name";
+----+-------------+----------+-------+---------------------+------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+-------+---------------------+------+---------+-------+------+-------+
| 1 | SIMPLE | my_table | const | name,idx_name_value | name | 62 | const | 1 | |
+----+-------------+----------+-------+---------------------+------+---------+-------+------+-------+
注意,如果删除唯一约束,
ALTER TABLE my_table DROP INDEX name;
覆盖索引按预期工作:
mysql> EXPLAIN
-> SELECT name, value
-> FROM my_table
-> WHERE name = "my_name";
+----+-------------+----------+------+----------------+----------------+---------+-------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+----------------+----------------+---------+-------+------+--------------------------+
| 1 | SIMPLE | my_table | ref | idx_name_value | idx_name_value | 62 | const | 1 | Using where; Using index |
+----+-------------+----------+------+----------------+----------------+---------+-------+------+--------------------------+
那么,如何可以使用覆盖索引,并且还具有独特的约束?
我误解了覆盖索引的目的吗?我认为目的是通过消除查询记录的需要来加速数据检索,因为数据已经包含在索引中。 – alexpirine