Is there a drawback to crate a unique key containing fields A, B, C and then create another one with fields C, B, A, so MySQL will take advantage of the index in case of searching only with A and only with C?
-
More memory or disk space used... – Tim Dearborn Dec 21 '13 at 04:37
-
@BrianRoach: I am just a beginner, but accoding to MySQL docs, it will help, I think... or not? – Blazer Dec 21 '13 at 04:39
-
2Actually, I forgot with mySQL you get a benefit on leftmost. See: http://stackoverflow.com/a/1823818/302916. That said ... if you're never going to use the composite key, why waste the space? You need to figure out what your use patterns are and index accordingly. – Brian Roach Dec 21 '13 at 04:44
1 Answers
You don't want to create an additional composite UNIQUE
constraint. The case when you access your data by only A
is already covered by existing index (a, b, c)
. If you need to support queries with access path only by c
then you can create an index just on c
.
If your schema looks something like
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
If you filter on A
only you'll see that unique index is properly used because A
is the leftmost prefix (keylen = 4
) of the index. Extra
column in EXPLAIN
results shows 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)
Now if you try filter on C
then you'll see a different story. EXPLAIN
shows that MySQL is in fact using unique index but is doing full index scan (type = index
) with a filter predicate identified by Using where
in Extra
column.
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)
Here is SQLFiddle demo
If we create an explicit index on C
mysql> create index idx_c on tablex (c); Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0
and take a look at EXPLAIN
we'll see again 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)
Here is SQLFiddle demo

- 91,357
- 15
- 148
- 157