最近我一直在想我的数据库索引,过去我只是一种非夸张地把它们抛入其中,并且从未真正考虑过它们是否正确或甚至帮助。我读过冲突的信息,有人说更多的索引更好,其他人索引太多都不好,所以我希望能够澄清一些,并在这里学习一下。需要对MySQL索引进行一点说明
比方说,我有这样的假设表:
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
);
我通常会添加索引将被加入,将上最常被排序字段和字段:
ALTER TABLE widgets ADD INDEX widget_name_index(widget_name);
所以现在,在查询中,例如:
SELECT w.* FROM widgets AS w ORDER BY w.widget_name ASC
的widget_name_index
用于SOR结果集。
现在,如果我添加一个搜索参数:
SELECT w.* FROM widgets AS w
WHERE w.widget_price > 100.00
ORDER BY w.widget_name ASC
我想我需要一个新的索引。
ALTER TABLE widgets ADD INDEX widget_price_index(widget_price);
但是,它会使用两个索引吗?据我所知也不会......
ALTER TABLE widgets ADD INDEX widget_price_name_index(widget_price, widget_name);
现在widget_price_name_index
将用于两个选择和订购的记录。但是,如果我想扭转局面,并做什么:
SELECT w.* FROM widgets AS w
WHERE w.widget_name LIKE '%foobar%'
ORDER BY w.widget_price ASC
将widget_price_name_index
用于此?或者我还需要widget_name_price_index
?
ALTER TABLE widgets ADD INDEX widget_name_price_index(widget_name, widget_price);
现在,如果我有搜索widget_name
,widget_part_number
和widget_description
一个搜索框?
ALTER TABLE widgets
ADD INDEX widget_search(widget_name, widget_part_number, widget_description);
如果最终用户可以按任何列进行排序,该怎么办?很容易看到,如果我只有5列的话,我可能会得到十多个索引。
如果再加上另一个表:
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
我假定这将使用大约排序widget_id_index
和widgets.widget_id
主键索引的加盟,但什么?它会同时使用widget_name_index
和special_title_index
?
我不想漫步太久,有无数场景可以让我想起来。显然,这可能会变得更加复杂与真实世界的场景,而不是几个简单的表。任何澄清将不胜感激。
我不会把这作为答案,因为我不是专业的数据库,但在MySQL中,您可以在查询之前使用EXPLAIN来提供有关使用哪些索引的一些信息。 http://dev.mysql.com/doc/refman/5.0/en/explain.html – MitMaro 2009-11-21 04:05:47