34

我有一个表,我需要从中获取按字段降序排列的行。运行如下EXPLAIN查询时:

EXPLAIN SELECT ... FROM table WHERE ... ORDER BY field DESC

我进入Using where; Using filesort专栏Extra。所以我尝试创建一个DESC索引:

CREATE INDEX name ON table (field DESC);

但是当我再次运行时,我在列中EXPLAIN得到相同的结果,并且性能几乎相同。Using where; Using filesortExtra

我究竟做错了什么?

4

3 回答 3

58

这是 MySQL 的“功能”之一,它会默默地忽略您做某事的请求,因为它根本没有实现:

来自http://dev.mysql.com/doc/refman/5.5/en/create-index.html

index_col_name 规范可以以 ASC 或 DESC 结尾。这些关键字允许将来扩展以指定升序或降序索引值存储。目前,它们被解析但被忽略;索引值始终按升序存储

于 2012-04-11T15:33:42.077 回答
13

MySQL 从版本 8 开始支持降序索引。在早期版本中,“DESC”子句在创建索引时被忽略。对于 (a) 单列索引或 (b) 所有列都有一个方向的多列索引来说,这不是问题:要么全是 ASC,要么全是 DESC——因为索引是双向的。

但是,如果您需要一个列方向不同的多列索引,例如,您可以像这样运行多个查询:

SELECT * from MyTable WHERE ColumnA = 1 ORDER BY ColumnB ASC, ColumnC DESC

您需要以下索引:(ColumnA,ColumnB ASC,ColumnC DESC)。

您可以在 MySQL 8 之前的版本中使用这些参数创建索引,但实际上它是静默创建的,所有列都升序(ColumnA ASC、ColumnB ASC、ColumnC ASC)。

因此,您的查询无法完全使用该索引 - 它只从索引中获取列 A 和 B,而对列 C 使用未索引(文件排序)数据。

在 MySQL 8.0 及更高版本中,这将不再是问题。见https://dev.mysql.com/doc/refman/8.0/en/descending-indexes.html

MySQL 版本 8 已于 2018 年 4 月 19 日 (v8.0.11) 发布以供普遍使用。

于 2017-05-11T17:24:21.503 回答
12

As mentioned the feature is not implemented but some workarounds may be of interest:

One possibility is to store the field in a negated or reverse value.

If it is a number you can store (-n) or (MAXVAL -n) if unsigned

If it's a date or timestamp, some would advocate to store a number instead and use functions such as FROM_UNIXTIME()

Of course such change is not always easily done... depends on existing code etc.

于 2014-12-03T22:11:47.253 回答