Ultimamente ho pensato ai miei indici di database, in passato mi sono semplicemente scordato in modo non cauto in un secondo momento, e non ci ho mai pensato molto se sono corretti o anche aiutando. Ho letto informazioni contrastanti, alcuni dicono che più indici sono migliori e altri che troppi indici sono cattivi, quindi spero di ottenere qualche chiarimento e di imparare un po 'qui.Ho bisogno di un po 'di chiarimenti sugli indici MySQL
Diciamo che ho questo ipotetico tavolo:
CREATE TABLE widgets (
widget_id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
widget_name VARCHAR(50) NOT NULL,
widget_part_number VARCHAR(20) NOT NULL,
widget_price FLOAT NOT NULL,
widget_description TEXT NOT NULL
);
avrei tipicamente aggiungere un indice per i campi che verranno unite e campi che saranno ordinati il più delle volte:
ALTER TABLE widgets ADD INDEX widget_name_index(widget_name);
Così ora , in una ricerca del tipo:
SELECT w.* FROM widgets AS w ORDER BY w.widget_name ASC
Il widget_name_index
è utilizzato per Sor t il set di risultati.
Ora, se posso aggiungere un parametro di ricerca:
SELECT w.* FROM widgets AS w
WHERE w.widget_price > 100.00
ORDER BY w.widget_name ASC
Credo che ho bisogno di un nuovo indice.
ALTER TABLE widgets ADD INDEX widget_price_index(widget_price);
Ma, utilizzerà entrambi gli indici? A quanto mi risulta non lo farà ...
ALTER TABLE widgets ADD INDEX widget_price_name_index(widget_price, widget_name);
Ora widget_price_name_index
saranno utilizzati sia per selezionare e ordinare i record. Ma cosa succede se voglio girare intorno e fare questo:
SELECT w.* FROM widgets AS w
WHERE w.widget_name LIKE '%foobar%'
ORDER BY w.widget_price ASC
Sarà widget_price_name_index
essere utilizzato per questo? O ho anche bisogno di un widget_name_price_index
?
ALTER TABLE widgets ADD INDEX widget_name_price_index(widget_name, widget_price);
Ora che cosa se ho una casella di ricerca che cerca widget_name
, widget_part_number
e widget_description
?
ALTER TABLE widgets
ADD INDEX widget_search(widget_name, widget_part_number, widget_description);
E se gli utenti finali possono ordinare in base a qualsiasi colonna? È facile vedere come potrei finire con più di una dozzina di indici per solo 5 colonne.
Se si aggiunge un altro tavolo:
CREATE TABLE specials (
special_id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
widget_id INT UNSIGNED NOT NULL,
special_title VARCHAR(100) NOT NULL,
special_discount FLOAT NOT NULL,
special_date DATE NOT NULL
);
ALTER TABLE specials ADD INDEX specials_widget_id_index(widget_id);
ALTER TABLE specials ADD INDEX special_title_index(special_title);
SELECT w.widget_name, s.special_title
FROM widgets AS w
INNER JOIN specials AS s ON w.widget_id=s.widget_id
ORDER BY w.widget_name ASC, s.special_title ASC
Io parto dal presupposto questo userà widget_id_index
e l'indice chiave primaria widgets.widget_id
per il join, ma per quanto riguarda l'ordinamento? Utilizzerà sia widget_name_index
e special_title_index
?
Io non voglio divagare troppo a lungo, ci sono un numero infinito di scenari che potrei confondere. Ovviamente questo può diventare molto più complesso con gli scenari del mondo reale piuttosto che con un paio di semplici tabelle. Qualsiasi chiarimento sarebbe apprezzato.
Non metto questo come risposta dato che non sono un professionista quando si tratta di database, ma in mysql puoi usare EXPLAIN prima di una query per fornire alcune informazioni su quali indici sono usati. http://dev.mysql.com/doc/refman/5.0/en/explain.html – MitMaro