【发布时间】:2010-12-18 23:15:59
【问题描述】:
我最近一直在考虑我的数据库索引,过去我只是在事后才毫不客气地把它们扔进去,从来没有真正考虑过它们是否正确甚至有帮助。我读过相互矛盾的信息,有人说索引越多越好,而其他人说索引太多不好,所以我希望在这里得到一些澄清和了解。
假设我有这个假设的表格:
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 用于对结果集进行排序。
现在如果我添加一个搜索参数:
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 来提供有关使用哪些索引的一些信息。 dev.mysql.com/doc/refman/5.0/en/explain.html
标签: mysql database-design indexing database