2013-12-21 5 views
0

Есть ли недостаток в создании уникального ключа, содержащего поля A, B, C, а затем создания другого с полями C, B, A, поэтому MySQL будет использовать индекс в случае поиска только с A и только с C?MySQL несколько уникальных ключей, недостаток

+0

Больше памяти или дискового пространства используется ... –

+0

@BrianRoach: Я только начинающий, но Accoding к MySQL документации, это поможет, я думаю ... или нет? – Blazer

+2

На самом деле, я забыл с mySQL, что вы получаете преимущество в самом левом. См. Http://stackoverflow.com/a/1823818/302916. Тем не менее ... если вы никогда не будете использовать сложный ключ, зачем тратить пространство? Вам нужно выяснить, каковы ваши шаблоны использования и соответственно индексировать. –

ответ

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 column в 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 демо

Смежные вопросы