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
