Uma restrição UNIQUE cria automaticamente um INDEX no (s) campo (s)?

97

Devo definir um índice separado na emailcoluna (para fins de pesquisa) ou o índice é adicionado "automaticamente" junto com a UNIQ_EMAIL_USERrestrição?

CREATE TABLE IF NOT EXISTS `customer` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `first` varchar(255) NOT NULL,
  `last` varchar(255) NOT NULL,
  `slug` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UNIQ_SLUG` (`slug`),
  UNIQUE KEY `UNIQ_EMAIL_USER` (`email`,`user_id`),
  KEY `IDX_USER` (`user_id`)
) ENGINE=InnoDB;

EDITAR : conforme sugerido por Corbin, perguntei EXPLAIN SELECT * FROM customer WHERE email = 'address'em uma tabela vazia. Esse é o resultado, não sei interpretar:

id select_type type possible_keys key  key_len ref  rows Extra
1  SIMPLE      ALL  NULL          NULL NULL    NULL 1    Using where

Ao adicionar um IXD_EMAIL à tabela, a mesma consulta mostra:

id select_type type possible_keys key       key_len ref   rows Extra
1  SIMPLE      ref  IDX_EMAIL     IDX_EMAIL 257     const 1    Using where
Gremo
fonte
1
Uma restrição UNIQUE não requer tecnicamente um índice ... mas não tenho certeza de como o padrão o define ou o MySQL (qual backend, btw?) O implementa. Tudo o que posso encontrar no MySQL manualmente rapidamente é "Um índice UNIQUE cria uma restrição de forma que todos os valores no índice devem ser distintos.".
Você precisa implementar e testar com índices individuais vs de cobertura (AKA composto - mais de uma coluna). Depende do uso e dos dados.
OMG Ponies
3
Tenho 99% de certeza de que ele realmente cria um índice. Basta criar uma tabela com um exclusivo e, em seguida, explicar em um select com um onde.
Corbin
@Corbin fez isso, como devo interpretar o resultado?
gremo
Ele usou a restrição exclusiva como um índice? A propósito, você pode precisar usar uma mesa significativamente grande ou pode apenas fazer uma varredura na tabela.
Corbin

Respostas:

115

Uma chave exclusiva é um caso especial de índice, agindo como um índice regular com verificação adicional de exclusividade. Usando SHOW INDEXES FROM customervocê pode ver que suas chaves exclusivas são, na verdade, índices do tipo B-tree.

Um índice composto de (email, user_id)for suficiente, você não precisa de um índice separado apenas em e-mail - MySQL pode usar peças mais à esquerda de um índice composto. Pode haver alguns casos de fronteira em que o tamanho de um índice pode tornar suas consultas mais lentas, mas você não deve se preocupar com eles até que realmente os encontre.

Quanto ao teste de uso do índice, primeiro você deve preencher sua tabela com alguns dados para fazer o otimizador pensar que realmente vale a pena usar esse índice.

piotrm
fonte
Portanto, o EXPLAINteste mostra valores falsos por causa da tabela vazia?
gremo
Não tenho certeza de como você conseguiu esse resultado de explain, acabei de copiar sua definição de tabela e o mesmo explain mostra UNIQ_EMAIL_USER como chave possível, você pode verificar novamente?
piotrm
Ok, encontrei o truque. Quando a restrição é definida usando user_idfirst e então emailela não aparece em EXPLAIN. Você está ciente disto?
gremo
10
Não funciona porque o email não é a parte mais à esquerda do par (user_id, email). Você não pode descer a árvore B para encontrar sua linha usando apenas a parte mais à direita.
piotrm