You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL 5.7中order by created_time desc与order by -created_time的区别及性能差异

为什么order by created_time desc和order by -created_time性能差异巨大?

现象重现

在MySQL 5.7环境下,针对1000万行数据的表执行两个逻辑结果一致的查询,耗时差异显著:

-- 耗时0.018秒
select SQL_NO_CACHE * from sample.points_full_table where created_time > '2023-01-01' order by created_time desc limit 1000;
-- 耗时5.323秒
select SQL_NO_CACHE * from sample.points_full_table where created_time > '2023-01-01' order by -created_time limit 1000;

执行计划对比

order by created_time desc执行计划:

idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEpoints_full_tablerangecreated_time_indexcreated_time_index54986750100.00Using index condition

order by -created_time执行计划:

idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEpoints_full_tableALLcreated_time_index997350050.00Using where; Using filesort

性能差异原因解析

  1. 索引的直接复用能力
    created_time_index是基于created_time字段构建的B+树索引,本身按升序存储。MySQL支持反向扫描索引,因此order by created_time desc可以直接从索引的末尾(最大的created_time值)开始向前读取,同时结合where created_time > '2023-01-01'的条件快速定位起始位置,直接取出前1000条数据,全程不需要额外排序,效率极高。

  2. 计算表达式破坏索引可用性
    当使用order by -created_time时,相当于对created_time执行了算术变换操作。MySQL无法直接利用现有索引来获取计算后的值的有序性,因为索引中存储的是原始created_time值,而非其负值。此时优化器无法通过索引满足排序需求,只能选择:

    • 先全表扫描所有数据,过滤出符合created_time > '2023-01-01'的记录;
    • 对过滤后的近500万条数据执行内存/磁盘排序(即Using filesort);
    • 最后取排序后的前1000条数据。
      全表扫描+大规模排序的组合直接导致耗时剧增。
  3. 优化器的决策逻辑
    第二个查询中,排序条件是经过计算的表达式,优化器判断无法通过索引覆盖排序需求,因此放弃使用created_time_index,转而选择全表扫描。而第一个查询的排序条件与索引完全匹配,优化器直接选择走索引,同时满足过滤、排序、取数三个需求,避免了冗余操作。

内容的提问来源于stack exchange,提问作者Andy Su

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 13:53:19