Une contrainte UNIQUE crée-t-elle automatiquement un INDEX sur le (s) champ (s)?

97

Dois-je définir un index séparé sur la emailcolonne (à des fins de recherche), ou est-ce que l'index est ajouté "automatiquement" avec la UNIQ_EMAIL_USERcontrainte?

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;

EDIT : comme suggéré par Corbin, j'ai demandé EXPLAIN SELECT * FROM customer WHERE email = 'address'sur une table vide. Voici le résultat, je ne sais pas comment l'interpréter:

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

Lors de l'ajout d'un IXD_EMAIL à la table, la même requête montre:

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
la source
1
Une contrainte UNIQUE ne nécessite pas techniquement un index ... mais je ne sais pas comment la norme la définit ou MySQL (quel backend, btw?) L'implémente. Tout ce que je peux trouver dans MySQL manuellement est "Un index UNIQUE crée une contrainte telle que toutes les valeurs de l'index doivent être distinctes.".
Vous devez implémenter et tester avec des index individuels vs couvrant (AKA composite - plus d'une colonne). Cela dépend de l'utilisation et des données.
OMG Ponies
3
Je suis sûr à 99% que cela crée effectivement un index. Créez simplement une table avec un unique puis faites une explication sur une sélection avec un où.
Corbin
@Corbin l'a fait, comment dois-je interpréter le résultat?
gremo
A-t-il utilisé la contrainte unique comme index? Vous devrez peut-être utiliser une table beaucoup plus grande ou faire simplement une analyse de table.
Corbin

Réponses:

115

Une clé unique est un cas particulier d'index, agissant comme un index normal avec une vérification supplémentaire de l'unicité. En utilisant, SHOW INDEXES FROM customervous pouvez voir que vos clés uniques sont en fait des index de type B-tree.

Un index composite sur (email, user_id)suffit, vous n'avez pas besoin d'un index séparé uniquement sur les e-mails - MySQL peut utiliser les parties les plus à gauche d'un index composite. Il peut y avoir des cas limites où la taille d'un index peut ralentir vos requêtes, mais vous ne devriez pas vous en préoccuper tant que vous ne les rencontrez pas.

En ce qui concerne le test de l'utilisation de l'index, vous devez d'abord remplir votre table avec des données pour que l'optimiseur pense qu'il vaut vraiment la peine d'utiliser cet index.

piotrme
la source
Alors le EXPLAINtest montre des valeurs fausses à cause de la table vide?
gremo
Je ne sais pas comment vous avez réussi à obtenir ce résultat d'explication, je viens de copier la définition de votre table et la même explication montre UNIQ_EMAIL_USER comme clé possible, pouvez-vous la revérifier?
piotrm
Ok, j'ai trouvé l'astuce. Lorsque la contrainte est définie en utilisant d' user_idabord, puis emailelle n'apparaît pas dans EXPLAIN. Etes-vous conscient de cela?
gremo
10
Cela ne fonctionne pas car l'e-mail n'est pas une partie la plus à gauche de la paire (user_id, email). Vous ne pouvez pas descendre dans le b-tree pour trouver votre ligne en utilisant uniquement la partie la plus à droite.
piotrm