Un vincolo UNIQUE crea automaticamente un INDICE sui campi?


97

Devo definire un indice separato sulla emailcolonna (per scopi di ricerca), o l'indice viene aggiunto "automaticamente" insieme al UNIQ_EMAIL_USERvincolo?

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 : come suggerito da Corbin che ho chiesto EXPLAIN SELECT * FROM customer WHERE email = 'address'su un tavolo vuoto. Questo è il risultato, non so come interpretarlo:

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

Durante l'aggiunta di un IXD_EMAIL alla tabella, la stessa query 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

1
Un vincolo UNICO non richiede tecnicamente un indice ... ma non sei sicuro di come lo standard lo definisce o MySQL (quale backend, btw?) Lo implementa. Tutto quello che posso trovare rapidamente in MySQL è "UN indice UNICO crea un vincolo tale che tutti i valori nell'indice devono essere distinti.".

È necessario implementare e testare con indici individuali e di copertura (AKA composito - più di una colonna). Dipende dall'uso e dai dati.
OMG Pony

3
Sono sicuro al 99% che crei effettivamente un indice. Basta creare una tabella con un unico quindi fare una spiegazione su una selezione con un dove.
Corbin

@Corbin l'ha fatto, come devo interpretare il risultato?
gremo

Ha utilizzato il vincolo univoco come indice? Potrebbe essere necessario utilizzare una tabella molto grande, oppure potrebbe semplicemente eseguire una scansione della tabella.
Corbin

Risposte:


115

Una chiave univoca è un caso speciale di indice, che agisce come un normale indice con l'aggiunta del controllo per l'unicità. Usando SHOW INDEXES FROM customerpuoi vedere che le tue chiavi univoche sono in realtà indici di tipo B-tree.

Un indice composto su (email, user_id)è sufficiente, non è necessario un indice separato solo per la posta elettronica: MySQL può utilizzare le parti più a sinistra di un indice composto. Potrebbero esserci dei casi limite in cui la dimensione di un indice può rallentare le tue query, ma non dovresti preoccuparti di loro finché non li incontri effettivamente.

Per quanto riguarda il test dell'utilizzo dell'indice, dovresti prima riempire la tabella con alcuni dati per fare in modo che l'ottimizzatore pensi che valga davvero la pena usare quell'indice.


Quindi il EXPLAINtest mostra valori falsi a causa della tabella vuota?
gremo

Non sono sicuro di come sei riuscito a ottenere il risultato della spiegazione, ho appena copiato la definizione della tua tabella e la stessa spiegazione mostra UNIQ_EMAIL_USER come possibile chiave, puoi ricontrollare per favore?
piotrm

Ok, ho trovato il trucco. Quando il vincolo viene definito utilizzando user_idfirst e poi emailnon viene visualizzato in EXPLAIN. Ne sei consapevole?
gremo

10
Non funziona perché l'email non è la parte più a sinistra della coppia (user_id, email). Non puoi scendere b-tree per trovare la tua riga usando solo la parte più a destra.
piotrm
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.