【问题标题】:How do I create a DESC index in MySQL?如何在 MySQL 中创建 DESC 索引?
【发布时间】:2012-04-23 22:40:59
【问题描述】:

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

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

我在Extra 列中得到Using where; Using filesort。所以我尝试创建一个DESC 索引:

CREATE INDEX name ON table (field DESC);

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

我做错了什么?

【问题讨论】:

    标签: mysql performance


    【解决方案1】:

    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)。

    【讨论】:

      【解决方案2】:

      如前所述,该功能尚未实现,但可能有一些解决方法:

      一种可能性是将字段存储在否定值或反向值中。

      如果它是一个数字,你可以存储 (-n) 或 (MAXVAL -n) 如果无符号

      如果是日期或时间戳,有些人会提倡存储一个数字,并使用 FROM_UNIXTIME() 等函数

      当然,这样的改变并不总是容易做到的……取决于现有的代码等。

      【讨论】:

      • 当方向相同时,即所有 ASC 或所有 DESC,则在 mysql 5,7 和更早版本中没有性能下降。只有当 ASC 和 DESC 混合使用时,您才需要像 mysql 5.7 或更早版本中的虚拟字段这样的解决方法。 MySQL 8 在混合使用 ASC 和 DESC 时进行了优化。参考percona.com/blog/2016/10/20/…
      【解决方案3】:

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

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

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

      【讨论】:

      • “哈希”索引也是如此。为什么 MySQL 开发人员允许他们的“CREATE INDEX”语句中的所有内容但不实现任何内容?
      • 这在 MySQL 8.0 中已经过时了;查看另一个答案。
      猜你喜欢
      • 2021-02-21
      • 1970-01-01
      • 2018-01-24
      • 2016-12-20
      • 2020-10-12
      • 1970-01-01
      • 1970-01-01
      • 2012-11-26
      • 2013-06-22
      相关资源
      最近更新 更多