【发布时间】:2014-07-29 02:07:48
【问题描述】:
我通过“高性能 MySQL”一书学习 MySQL 索引详细信息,但我无法理解一件事。
正如书中所说,(第 124 页使用索引扫描进行排序)
MySQL 有两种方法来产生有序的结果:它可以使用文件排序, 或者它可以按顺序扫描索引。
仅当索引的顺序为 与 ORDER BY 子句完全相同,所有列都按 相同的方向(上升或下降)。
ORDER BY 子句也具有与查找查询相同的限制:它 需要形成索引的最左前缀。在所有其他情况下, MySQL 使用文件排序。
此外,作者给出了一些使用 MySQL Sakila 的示例数据库的示例 [http://dev.mysql.com/doc/sakila/en/][1]
第一个例子运行良好:
标准 Sakila 示例数据库中的出租表有一个索引 (rental_date、inventory_id、customer_id):
CREATE TABLE rental (
...
PRIMARY KEY (rental_id),
UNIQUE KEY rental_date (rental_date,inventory_id,customer_id),
KEY idx_fk_inventory_id (inventory_id),
KEY idx_fk_customer_id (customer_id),
KEY idx_fk_staff_id (staff_id),
...
);
MySQL 使用 rent_date 索引来排序以下查询,因为您 从 EXPLAIN 中缺少文件排序可以看出:
> mysql> EXPLAIN SELECT
> rental_id, staff_id FROM sakila.rental
> -> WHERE rental_date = '2005-05-25'
> -> ORDER BY inventory_id, customer_id\G
> *************************** 1. row ***************************
> type: ref
> possible_keys: rental_date
> key: rental_date
> rows: 1
> Extra: Using where
即使 ORDER BY 子句本身不是 索引的最左边前缀,因为我们指定了相等 索引中第一列的条件。
需要注意的是:它们在 where 子句中使用索引列,但在 SELECT 查询中使用不同的列。
第二个例子简明扼要:
以下查询也有效,因为 ORDER BY 中的两列 是索引的最左侧前缀:
... WHERE rent_date > '2005-05-25' ORDER BY rent_date,inventory_id;
但在这里您可以获得不同的结果,而不是您的 SELECT 列内容:
第一种情况,使用文件排序:
EXPLAIN
SELECT `rental_id`, `staff_id` FROM `sakila`.`rental`
WHERE `rental_date` > '2005-05-25'
ORDER BY `rental_date`, `inventory_id`;
类型:全部
可能的密钥:出租日期
键:空
额外:使用where;使用文件排序
第二种情况,使用索引:
EXPLAIN
SELECT `rental_id`, `rental_date`, `inventory_id` FROM `sakila`.`rental`
WHERE `rental_date` > '2005-05-25'
ORDER BY `rental_date`, `inventory_id`;
类型:范围 possible_key:出租日期 键:rental_date 额外:使用where;使用索引
为什么它会以这种奇怪的方式工作?如前所示,第一个示例使用索引排序,即使在 SELECT 子句中使用 WHERE 子句包含不同的列。
【问题讨论】: