mysql order by -id vs order by id desc

Posted

技术标签:

【中文标题】mysql order by -id vs order by id desc【英文标题】: 【发布时间】:2015-02-26 14:07:18 【问题描述】:

我希望从 1 M 行的表中获取最后 10 行。

CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `updated_date` datetime NOT NULL,
  PRIMARY KEY (`id`)
)

这样做的一种方法是 -

select * from test order by -id limit 10;

**10 rows in set (0.14 sec)**

另一种方法是 -

select * from test order by id desc limit 10;

**10 rows in set (0.00 sec)**

所以我对这些查询做了一个“解释”-

这是我使用 'order by desc' 的查询结果

EXPLAIN select * from test order by id desc limit 10;

这是我使用'order by -id'的查询结果

EXPLAIN select * from test order by -id limit 10;

我认为这将是相同的,但执行计划似乎存在差异。

【问题讨论】:

您是否在同一会话上运行了两个查询?有时这可能只是因为数据库现金而发生。 @smn_onrocks 你的意思是“数据库缓存”对吧? @JakeGould 是的,没错 【参考方案1】:

RDBMS 使用启发式算法来计算执行计划,它们不能总是确定两条语句的语义等价,因为这是一个太难的问题(就理论和实践的复杂性而言)。

因此 mysql 无法使用索引,因为您在“-id”上没有索引,这是应用于字段“id”的自定义函数。看起来微不足道,但 RDBMS 必须最大限度地减少计算计划所需的时间,因此它们会遇到简单的问题。

当无法为查询找到优化(即使用索引)时,系统会退回到在任何情况下都有效的实现:扫描整个表。

【讨论】:

【参考方案2】:

您将 ORDER BY 与包含键列名称以外的术语的表达式一起使用:

SELECT * FROM t1 ORDER BY ABS(key);

SELECT * FROM t1 ORDER BY -key;

您只索引在 ORDER BY 子句中命名的列的前缀。在这种情况下,索引不能用于完全解析排序顺序。例如,如果您有一个 CHAR(20) 列,但仅索引前 10 个字节,则索引无法区分第 10 个字节之后的值,因此需要进行文件排序。

使用的表索引类型不按顺序存储行。例如,这适用于 MEMORY 表中的 HASH 索引。

请点击此链接:http://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html

【讨论】:

【参考方案3】:

正如您在解释结果中看到的那样,

1 : order by id MySQL 在id 上使用索引。所以它只需要迭代 10 行,因为它已经被索引了。而且在这种情况下,MySQL 也不需要使用filesort 算法,因为它已经被索引了。

2 : order by -id MySQL id 上使用索引。所以它需要迭代所有的行。(例如455952)来得到你预期的结果。在这种情况下,MySQL 需要使用filesort 算法,因为id 没有被索引。所以显然需要更多时间:)

【讨论】:

以上是关于mysql order by -id vs order by id desc的主要内容,如果未能解决你的问题,请参考以下文章

ORDER BY 优化是不是在以下 SELECT 语句中生效?

Sql Server 按偏移量分页行 - 没有'ORDER BY'

Hive SORT BY vs ORDER BY vs DISTRIBUTE BY vs CLUSTER BY

Hive : SORT BY vs ORDER BY vs DISTRIBUTE BY vs CLUSTER BY

Hive cluster by vs order by vs sort by

sql语句select group by order by where一般先后顺序