MySQL多个唯一键,缺点

时间:2013-12-21 04:36:13

标签: mysql

包含字段A,B,C的唯一键是否存在缺陷,然后创建另一个包含字段C,B,A的密钥,因此MySQL将在仅使用A进行搜索时利用索引C 1

1 个答案:

答案 0 :(得分:1)

您不希望创建其他复合UNIQUE约束。仅A访问您的数据的情况已由现有索引(a, b, c)涵盖。如果您只需c支持具有访问路径的查询,则可以在c上创建索引。

如果您的架构看起来像

mysql> create table tablex 
    -> (
    ->   a int not null, 
    ->   b int not null, 
    ->   c int not null
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql> insert into tablex values (1, 2, 3),(2, 3, 4),(1, 3, 3);
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> create unique index idx_abc_unique on tablex (a, b, c);
Query OK, 0 rows affected (0.06 sec)
Records: 0  Duplicates: 0  Warnings: 0

如果您对A进行过滤,则只会看到正确使用唯一索引,因为A是索引的最左前缀(keylen = 4)。 Extra结果中的EXPLAIN列显示Using index

mysql> explain select * from tablex where a = 1;
+----+-------------+--------+------+----------------+----------------+---------+-------+------+-------------+
| id | select_type | table  | type | possible_keys  | key            | key_len | ref   | rows | Extra       |
+----+-------------+--------+------+----------------+----------------+---------+-------+------+-------------+
|  1 | SIMPLE      | tablex | ref  | idx_abc_unique | idx_abc_unique | 4       | const |    1 | Using index |
+----+-------------+--------+------+----------------+----------------+---------+-------+------+-------------+
1 row in set (0.00 sec)

现在,如果你尝试过滤C,那么你会看到一个不同的故事。 EXPLAIN表明MySQL实际上使用的是唯一索引,但正在使用type = index列中Using where标识的过滤谓词进行完整索引扫描(Extra)。

mysql> explain select * from tablex where c = 3;
+----+-------------+--------+-------+---------------+----------------+---------+------+------+--------------------------+
| id | select_type | table  | type  | possible_keys | key            | key_len | ref  | rows | Extra                    |
+----+-------------+--------+-------+---------------+----------------+---------+------+------+--------------------------+
|  1 | SIMPLE      | tablex | index | NULL          | idx_abc_unique | 12      | NULL |    1 | Using where; Using index |
+----+-------------+--------+-------+---------------+----------------+---------+------+------+--------------------------+
1 row in set (0.00 sec)

这是 SQLFiddle 演示

如果我们在C

上创建显式索引
mysql> create index idx_c on tablex (c);
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

并查看EXPLAIN我们会再次看到Using index

mysql> explain select * from tablex where c = 3;
+----+-------------+--------+------+---------------+-------+---------+-------+------+-------------+
| id | select_type | table  | type | possible_keys | key   | key_len | ref   | rows | Extra       |
+----+-------------+--------+------+---------------+-------+---------+-------+------+-------------+
|  1 | SIMPLE      | tablex | ref  | idx_c         | idx_c | 4       | const |    1 | Using index |
+----+-------------+--------+------+---------------+-------+---------+-------+------+-------------+
1 row in set (0.00 sec)

这是 SQLFiddle 演示