当前位置: 首页 > news >正文

MySQL ORDER BY 原理与优化

ORDER BY 是 SQL 里最常见的子句之一,但用不好就是性能杀手。这篇说说 ORDER BY 的原理和优化方法。

ORDER BY 的执行原理

-- 简单 ORDER BYSELECT*FROMorderORDERBYcreated_atDESC;

MySQL 处理 ORDER BY 的过程:

  1. 全表扫描:读取所有数据
    1. 排序:内存排序 or 外部排序
    1. 返回结果:排序后的数据
      如果数据量小,MySQL 用内存排序(Filesort);如果数据量大,就要用磁盘排序,性能很差。

Filesort:MySQL 的排序算法

MySQL 用 Filesort 做排序,虽然名字带「file」,但不一定用磁盘——内存够用就在内存排。

两种模式

模式1:全字段排序(ROWID Sort)

-- 只返回排序字段 + 主键EXPLAINSELECTorder_id,created_atFROMorderORDERBYcreated_at;
排序时:order_id, created_at(2个字段) 排序后:按 created_at 排,用主键回表取完整数据

模式2:索引覆盖排序(Index Sort)

-- 如果 ORDER BY 字段有索引,直接用索引CREATEINDEXidx_created_atONorder(created_at);SELECT*FROMorderORDERBYcreated_at;

直接读索引树,有序,不用再排。

什么情况下用索引排序?

-- ✅ 能用索引排序ORDERBYcreated_at-- 有索引ORDERBYuser_id,created_at-- 符合最左前缀WHEREuser_id=1ORDERBYcreated_at-- 索引覆盖-- ❌ 不能用索引排序ORDERBYcreated_atDESC,idASC-- DESC/ASC 混用ORDERBYcreated_at,updated_at-- 没有复合索引 (created_at, updated_at)WHEREcreated_at>'2024-01-01'ORDERBYcreated_at-- 范围查询后面的字段

Using filesort:什么时候出现?

EXPLAINSELECT*FROMorderORDERBYcreated_at;

Extra 列出现Using filesort,说明要额外排序。

常见原因

  1. 没有 ORDER BY 的索引
    1. ORDER BY 用了函数
    1. 混用 ASC/DESC
    1. 排序字段不在同一个索引里

优化 ORDER BY

1. 覆盖索引

-- 只需要排序字段 + 主键,建联合索引CREATEINDEXidx_user_id_createdONorder(user_id,created_at);-- 排序语句SELECTid,created_atFROMorderWHEREuser_id=1ORDERBYcreated_atDESC;

2. 分页优化

-- 深分页排序很慢SELECT*FROMorderORDERBYcreated_atDESCLIMIT1000000,10;-- 优化:用主键范围SELECT*FROMorderWHEREid<1000000ORDERBYidDESCLIMIT10;

3. 减少排序数据量

-- ❌ 全表排序SELECT*FROMorderORDERBYcreated_atDESC;-- ✅ 加 WHERE 条件,减少排序范围SELECT*FROMorderWHEREstatus='completed'ORDERBYcreated_atDESC;

4. 避免在 ORDER BY 里用函数

-- ❌ 索引失效ORDERBYYEAR(created_at)-- ✅ 改用范围查询WHEREcreated_at>='2024-01-01'ANDcreated_at<'2025-01-01'ORDERBYcreated_at

实战:EXPLAIN 看排序

EXPLAINSELECT*FROMorderORDERBYcreated_atDESC;-- type: ALL(全表扫描)-- key: NULL(没走索引)-- Extra: Using filesort(需要排序)

优化后

CREATEINDEXidx_created_atONorder(created_atDESC);EXPLAINSELECT*FROMorderORDERBYcreated_atDESC;-- type: index(扫索引树)-- key: idx_created_at(走了索引)-- Extra: Using index(索引覆盖,不需要回表!)

小结

优化方法效果
覆盖索引⭐⭐⭐⭐⭐ 最优
加 WHERE 条件⭐⭐⭐⭐
避免函数⭐⭐⭐
避免混用 ASC/DESC⭐⭐⭐
分页用主键范围⭐⭐⭐⭐

ORDER BY 优化的核心:让 ORDER BY 字段有索引让查询走索引而不是 filesort


相关阅读:

  • [MySQL 索引底层 B+ 树原理]
    • [MySQL 索引失效的七种情况]
    • [MySQL 分页查询优化]
http://www.rkmt.cn/news/1298678.html

相关文章:

  • taotoken助力初创团队低成本管理多个ai模型api调用
  • Nginx再曝严重安全漏洞说明了什么?
  • day-02
  • 电气设备、工业炉行业企业官网模板资源整理
  • 大厂集体验证原生统一多模态范式:底层底座先行,上层应用共生
  • 组队作业
  • 免费商用几何字体Outfit的终极指南:快速打造专业品牌视觉
  • 2025届必备的六大降重复率方案实测分析
  • 全球仅17家机构实测通过的ElevenLabs阿萨姆文语音部署白皮书(含ISO 639-3代码验证、Bhasha兼容性测试报告)
  • ABAP报表开发避坑指南:从CKM3数据抽取看MLKEY结构、CKMLHD表关联与成本组件映射
  • GitHub合规自动化:法律条款代码化与开源许可证检查实践
  • 面向科学计算Agent的Harness数值稳定性校验
  • 浏览器扩展实现AI提示词高效管理:从模板变量到工作流优化
  • 终极指南:如何用HttpCanary轻松抓取Android应用网络请求
  • RKNPU2嵌入式AI部署实战:从模型转换到板端优化的完整指南
  • Altium Designer20 从零到一:新手必备的安装与核心功能上手指南
  • 我的嵌入式项目踩坑记:用STM32的输入捕获功能给自制旋转编码器“把脉”
  • Windows Cleaner终极方案:5分钟告别C盘爆红,系统性能飙升200%
  • Office RibbonX Editor:免费开源工具助你轻松定制Office界面
  • 程序员转智能体开发,面试必问的20个问题,标准答案全在这里
  • 终极Photoshop图层批量导出指南:如何用免费脚本提升10倍工作效率
  • STM32嵌入式开发入门:从硬件配置到项目实战的完整学习路径
  • Unlock Music终极指南:如何在浏览器中免费解锁12种加密音乐格式
  • 航空发电机综合测试系统设计【附代码】
  • 如何快速构建智能语音交互系统:小智ESP32后端服务实战指南
  • 如何用FanControl实现电脑风扇智能控制:告别噪音,提升散热效率的终极指南
  • 电子制作入门:从工具选择到工作台搭建的完整指南
  • OpenClaw 小龙虾部署误区排查与正确安装方法
  • TCP断开连接四次挥手
  • 告别代码!用Orange 3可视化数据挖掘,5分钟搞定鸢尾花分类分析