He estado pensando en los índices de mi base de datos últimamente, en el pasado simplemente los lancé de forma caprichosa como una idea de último momento, y nunca pensé mucho si eran correctos o incluso ayudando He leído información contradictoria, algunos dicen que más índices son mejores y otros que demasiados índices son malos, así que espero obtener algunas aclaraciones y aprender un poco aquí.Necesito una pequeña aclaración sobre los índices de MySQL
Digamos que tengo esta tabla hipotética:
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
);
Me normalmente añadir un índice para los campos que se unirán y los campos que se pueden clasificar en más a menudo:
ALTER TABLE widgets ADD INDEX widget_name_index(widget_name);
Así que ahora , en una consulta, tales como:
SELECT w.* FROM widgets AS w ORDER BY w.widget_name ASC
El widget_name_index
se utiliza para SOR t el conjunto de resultados
Ahora bien, si puedo añadir un parámetro de búsqueda:
SELECT w.* FROM widgets AS w
WHERE w.widget_price > 100.00
ORDER BY w.widget_name ASC
supongo que necesito un nuevo índice.
ALTER TABLE widgets ADD INDEX widget_price_index(widget_price);
Pero, ¿usará ambos índices? Como lo entiendo no lo hará ...
ALTER TABLE widgets ADD INDEX widget_price_name_index(widget_price, widget_name);
Ahora widget_price_name_index
se utilizará tanto para seleccionar y ordenar los registros. Pero lo que si quiero darle la vuelta y hacer esto:
SELECT w.* FROM widgets AS w
WHERE w.widget_name LIKE '%foobar%'
ORDER BY w.widget_price ASC
Será widget_price_name_index
ser utilizado para esto? ¿O necesito un widget_name_price_index
también?
ALTER TABLE widgets ADD INDEX widget_name_price_index(widget_name, widget_price);
Ahora lo que si tengo un cuadro de búsqueda que busca en widget_name
, widget_part_number
y widget_description
?
ALTER TABLE widgets
ADD INDEX widget_search(widget_name, widget_part_number, widget_description);
¿Y si los usuarios finales pueden ordenar por cualquier columna? Es fácil ver cómo podría terminar con más de una docena de índices por tan solo 5 columnas.
Si añadimos otra tabla:
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
Estoy asumiendo para ello se utiliza widget_id_index
y el índice de clave principal widgets.widget_id
de la unión, pero ¿qué pasa con la clasificación? ¿Utilizará ambos widget_name_index
y special_title_index
?
No quiero dar vueltas por mucho tiempo, hay un sinfín de escenarios que podría conujure. Obviamente, esto puede ser mucho más complejo con escenarios del mundo real en lugar de un par de tablas simples. Cualquier aclaración sería apreciada.
No voy a poner esto como una respuesta, ya que no soy un experto en lo que respecta a bases de datos, pero en mysql puede usar EXPLAIN antes de una consulta para proporcionar información sobre qué índices se utilizan. http://dev.mysql.com/doc/refman/5.0/en/explain.html – MitMaro