当前位置:首页 > 文章列表 > 数据库 > MySQL > MySQL ORDER BY LIMIT 为什么有时不走过滤索引:排序索引、filesort 和核对方法

MySQL ORDER BY LIMIT 为什么有时不走过滤索引:排序索引、filesort 和核对方法

来源:17golang原创 2026-07-17 17:32:38 0浏览 收藏

订单列表只显示最近 20 条,接口却在高峰时偶尔变慢。EXPLAIN 里还出现了一个反直觉的现象:表上明明有按状态建的索引,优化器却选择按主键顺序读取,再边读边过滤。很多人看到这里就想强制索引,结果把一次局部波动改成了长期负担。先把问题拆开:这条 SQL 同时在争取更少的过滤行和更快的排序输出,LIMIT 会改变两者的成本权重。

实践要点

  • ORDER BY ... LIMIT 不能只看 WHERE 条件;排序索引与过滤索引可能给出不同的低成本路径。
  • 复合索引应围绕真实的等值条件和稳定排序字段设计,别为了一个列表页堆一串无用列。
  • EXPLAIN 用来读候选路径,受控的 EXPLAIN ANALYZE 才能看到实际读行和耗时;两者都要结合数据分布判断。

LIMIT 20 让“先过滤”与“先排序”发生竞争

看一个常见订单页:用户只看已支付订单,并要求按订单号倒序返回 20 条。过滤索引可以快速定位 status = 'PAID' 的范围,但若它无法同时满足 ORDER BY id DESC,服务器还要再排一次序。另一条路是沿着主键倒序读取,遇到已支付记录就收下,够 20 条就停;如果最近订单大多已支付,这条路可能更省。

反过来,若已支付记录在最近订单中很稀疏,按主键一路回扫会读过很多不匹配行,过滤索引加排序反而可能更合适。MySQL 官方文档说明,带 LIMIT 的排序查询会影响索引选择;可用有序索引时很快,若必须 filesort,则要先选出并排序匹配行。这里别急着给某一种路径贴“永远更快”的标签。

MySQL ORDER BY LIMIT 的原创工程证据截图,以低饱和执行计划对照展示排序索引边读边筛选与过滤索引后 filesort 的两条路径

先用 EXPLAIN 看清它准备怎样读取

先把线上真实条件缩成可复现的查询,再看 keyrowsExtra。下面的 SQL 只作为示意,订单状态、时间窗口和排序字段应替换成自己的业务条件。

EXPLAIN
SELECT id, status, created_at
FROM orders
WHERE status = 'PAID'
ORDER BY id DESC
LIMIT 20;
  • key 表示本次路径选择的索引,不等于“表上最好的索引”。
  • rows 是优化器预计要检查的行数;对 InnoDB 来说它是估算值,不能把它当成精确计数。
  • Extra 出现 Using filesort 说明排序没有直接由当前读取顺序解决,但它本身不是判定慢查询的结论。

把两条候选 SQL 的 keyrows、返回行数和响应时延放在一起看,才能知道瓶颈是筛选稀疏、排序量过大,还是回表读取的字段太宽。只盯着一个 Using filesort,很容易把原本读取很少的数据路径误判掉。

复合索引要同时服务筛选与稳定排序

如果产品定义是“某状态下按创建时间倒序,订单号做同时间的稳定次序”,索引和 SQL 的排序表达就应该一致。等值过滤列通常放在前面,随后才是排序列;把唯一的 id 放进排序,可以避免同一时间值下翻页顺序漂移。

CREATE INDEX idx_orders_status_created_id
ON orders (status, created_at, id);

SELECT id, created_at
FROM orders
WHERE status = 'PAID'
ORDER BY created_at DESC, id DESC
LIMIT 20;

这不是要求每个列表页都新增索引。它是一个待核对的候选结构:先确认 WHERE 与 ORDER BY 是否真是这个组合,再看写入成本、索引体积和已有索引能否复用。MySQL 官方文档也提醒,索引不是越多越好;每个额外索引都会占用空间,并增加插入、更新和删除的维护成本。

上面的查询只取 idcreated_at。若结果所需字段都在同一个索引里,就有机会作为覆盖索引读取,减少回到表数据页的需要。把 SELECT * 原样搬进来通常就失去这个条件,因此应先确认列表页真正渲染了哪些字段。

MySQL 复合索引与稳定排序的原创工程证据截图,低饱和查询窗口展示 status、created_at、id 对齐后由索引返回少量列表字段的核对结果

两个反例比“加索引”更值得先看

第一个反例是排序方向或列顺序和索引不一致。例如业务按 created_at DESC, id ASC 排序,索引却按另一种方向与顺序建立;不能凭肉眼认定它一定能复用排序。第二个反例是过滤条件本身范围很宽,或者一次查询需要取大量不在索引中的字段。此时即使索引名称看起来匹配,回表和读取量也可能抵消优势。

还有一种常见误区是只为一个低频后台页面加很宽的覆盖索引。读侧少了一点回表,写侧却让每次状态更新都多维护一份大索引。架构上的取舍不在“覆盖索引好不好”,而在这个读取模式是否足够高频、字段是否足够稳定、写入成本是否能接受。

把 prefer_ordering_index 当成对比开关,不当成长期答案

MySQL 针对带 ORDER BYLIMIT 的查询会偏向考虑有序索引。官方文档提供了 prefer_ordering_index 开关,便于比较另一条候选路径。更稳妥的做法是在隔离的会话或测试环境里做一次对比,不要直接把全局默认改掉。

SET SESSION optimizer_switch = 'prefer_ordering_index=off';

EXPLAIN
SELECT id, status, created_at
FROM orders
WHERE status = 'PAID'
ORDER BY id DESC
LIMIT 20;

这一步的价值是帮助理解“排序优先”和“过滤优先”各自会选什么,不是替业务定结论。需要实际度量时,EXPLAIN ANALYZE 会真正运行 SELECT 并报告测量数据,应该只对受控查询使用,避免把昂贵的生产读请求额外再跑一遍。

上线前按这张表收口

核对点应看到的结果异常时优先检查
排序稳定性ORDER BY 包含能打破并列的列同时间值或同状态值下是否有跳页、重复
索引形状等值条件与排序列和业务 SQL 对齐列顺序、方向、范围条件与现有索引
读取量实际检查行数与返回 20 行的目标相称过滤稀疏度、filesort、回表字段
写入代价新增索引没有明显拉高写入延迟索引宽度、更新频率、重复索引

相关问题

Using filesort 一出现就必须优化吗?

不一定。它说明当前排序没有直接按索引顺序完成,但还要看匹配行数、排序量和实际时延。少量数据上的 filesort 可能比沿着不合适的排序索引扫很多行更省。

为什么 ORDER BY 要加 id?

当主要排序列存在相同值时,加唯一列可以让返回顺序稳定。MySQL 文档也指出,只按非唯一排序列配合 LIMIT 时,并列行的相对次序不保证固定。

覆盖索引是不是越宽越好?

不是。只有高频读取确实需要的少量字段才值得考虑放进索引;宽索引会占空间,也会增加写入维护成本。

能直接在生产请求上跑 EXPLAIN ANALYZE 吗?

要谨慎。它会运行 SELECT 并收集测量结果。先在可控副本、低风险时间窗或等价测试数据上确认读取量,再决定是否需要线上抽样。

核对资料

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
RAG 知识库怎么防提示词注入:外部文档只能当资料,不能当指令RAG 知识库怎么防提示词注入:外部文档只能当资料,不能当指令
上一篇
RAG 知识库怎么防提示词注入:外部文档只能当资料,不能当指令
下一篇
下一篇
暂无
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • ljg-skills -
    ljg-skills
    ljg-skills 是李继刚开源的 AI 技能与提示词集合,面向大模型使用者整理了一批可复用的 prompt、角色设定和任务技能模板,适合用于学习提示词设计、搭建个人 AI 工作流和沉淀团队常用智能体能力。
    4535次使用
  • MELO音乐 - AI 音乐生成平台,支持多模态创作能力
    MELO音乐
    MELO音乐是一站式AI视频与音乐制作助手,对标suno, udio的高品质体验。提供伴奏生成、原创写词、无损导出、哼唱识曲、混音变声等全套音频与短视频编辑工具。无论是流行Kpop、电音说唱、民谣古风、摇滚儿歌还是商用轻音乐,MELO为你免费谱曲,轻松做同款!
    4209次使用
  • UniScribe - AI 免费在线音视频转文字平台
    UniScribe
    UniScribe 是一款 AI 音视频转文字与内容整理工具,支持上传音频、视频文件或粘贴 YouTube 链接,自动生成转写文本、摘要、思维导图和关键问题,并支持多格式导出,适合会议记录、课程学习、访谈整理和内容创作复盘。
    4168次使用
  • 剧云 - 免费 AI 智能中文剧本创作平台
    剧云
    剧云是专业中文剧本创作平台,安全稳定运行十余年,集成AI编剧、剧本医生审核、人物小传、剧情关系图、大纲编写、多人协作、Word导入导出、版权管控功能,数据安全防护,轻松高效创作剧本。
    4392次使用
  • 万象有声 - AI 一站式有声内容创作平台
    万象有声
    万象有声,一个专为有声创作者打造的新一代智能有声内容创作平台。平台提供专业的智能拆章、智能画本编辑、AI配音、AI生成音效、后期制作、智能对轨、智能审听等有声创作全流程工具,可以帮助创作者高效、低成本创作出引人入胜的有声作品。立即体验,让有声书制作更简单!
    4338次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码