有哪些 SQL 优化方法?
未标记
考查重点:扫描、排序、回表与锁等待。以执行计划和耗时定位扫描、回表、排序或锁等待,按瓶颈调整索引、列数、批量与事务;在结果不变条件下同数据复测
本题目录
参考答案
核心回答
SQL 优化的核心是:在结果语义不变的前提下,减少扫描、传输、计算和等待的成本。 我会先结合执行计划与实际耗时找到主要开销,再选择对应的方法。以 MySQL 8.4 的常见业务查询为例:
- 减少扫描和回表:围绕过滤、连接和排序需求设计索引,联合索引的列顺序要匹配查询;让条件尽量能在索引上形成有效定位范围,并评估覆盖查询的收益。
- 减少读取和返回的数据:只查需要的列,限制合理的时间、业务范围和返回行数,避免为了几条结果读出大量明细后在应用里过滤。
- 减少排序、聚合和连接的中间结果:尽早过滤无关数据,检查连接条件、结果放大和排序开销;业务不需要去重时才考虑
UNION ALL,不能为了快而改变结果。 - 减少重复调用:把循环中的逐条查询改为合适的批量读取或关联查询;批量写入也要控制批次,避免把很多小往返换成一个不可控的大事务。
- 减少等待:如果主要耗时来自锁等待、长事务或资源争用,应缩短事务、改进访问方式或处理竞争源,单改查询文本未必有效。
优化后还要验证结果与性能。命中了索引、消除了 filesort,或 SQL 写得更短,都不能单独证明它更快。
进一步解释
从查询方式出发设计索引和分页
以“查看某用户按创建时间排序的订单”为参考例子,可以评估 (user_id, created_at, id) 这样的索引,让用户过滤与时间顺序结合起来。是否需要再包含其他列,要权衡查询覆盖收益、索引体积和写入维护成本。
如果深分页主要消耗在跳过前面大量记录,可以在业务允许时改成游标分页:保留上一页最后的创建时间和唯一 ID,按相同排序继续查。时间可能重复,因此不能只用时间作为游标。它也不等价于任意跳到第几页,分页交互和一致性要求都要一起考虑。
若必须保留偏移分页,可以评估先定位窄索引中的主键,再获取所需明细,减少不必要的回表;但跳过大量索引项的工作并没有因此凭空消失。
查询改写首先要保持语义
按自然日筛选时间字段时,可以考虑直接表达清楚起止边界,避免为每一行重复计算日期;边界要与时区和字段含义一致。已有合适的函数索引时,也不能一概说“出现函数就不能使用索引”。
改写连接、子查询和聚合时,则要关注重复行、NULL、外连接及聚合前后的过滤含义。例如把外连接的条件从 ON 移到 WHERE,可能使原本要保留的行消失;COUNT(*) 与 COUNT(某列) 对空值的处理也不同。优化器本身还会做等价转换,因此 JOIN、IN、EXISTS 哪个更快,需要结合具体计划判断。
怎样判断改到了真正的瓶颈?
先定位值得优化的 SQL,结合调用频率与总资源消耗排序,而不只找单次最慢的一条。然后用普通 EXPLAIN 看估算的访问路径、扫描量、连接方式,以及排序、临时结果等信息。
如果估算与实际表现不一致,再看统计信息、参数取值和数据倾斜。MySQL 8.4 的 EXPLAIN ANALYZE 会实际执行语句,并给出运行行数、循环次数和耗时,需要按相应执行开销使用,不能当成只解析 SQL。
比较改动前后时,应保持数据规模、参数、并发和缓存条件尽量可比;既看响应时间,也看扫描量、CPU、I/O,以及新增索引对写入的影响。
常见追问
分析型大查询,加了索引仍然慢怎么办?
先看最终需要处理的数据量。如果过滤后仍有海量结果,继续加索引未必能消除读取、聚合、排序和传输这些结果的成本。
对于 Doris 这类分析引擎,可以从执行计划检查分区裁剪、连接顺序和数据分布,再用 Profile 看扫描、跨节点交换及各执行阶段的耗时。高频、口径稳定的分析可以评估预聚合或物化视图;海量明细出数也可能需要限定查询范围、分批或异步处理。预计算会带来存储、更新和数据新鲜度的取舍,不能直接套用 MySQL 点查索引的经验。
是不是应该尽量不用 JOIN、子查询、NULL 或 OR?
没有这样的通用规则。需要判断它们在当前引擎、数据和查询条件下产生了什么访问路径与中间结果。把一次合理的关联拆成大量应用层查询,反而可能增加往返和一致性问题。
参考资料
- 国内:JavaGuide:常见 SQL 优化手段总结:采用必要列、连接、分页、批量处理及慢 SQL 定位部分,说明各方法减少哪类成本,以及不能改变查询语义的条件。
- 国内:JavaGuide:MySQL 执行计划分析:采用访问路径、扫描估算和附加信息的说明,把索引、回表、排序等方法与具体瓶颈联系起来。
- 国内:美团技术团队:MySQL 索引原理及慢查询优化:采用开篇联合索引案例及综合相关查询的思路,解释索引为什么要服务实际负载,不能逐字段机械添加。
- 国外:MySQL 8.4:EXPLAIN Statement:核对普通计划分析与实际执行分析的区别,用运行行数、循环次数和耗时检验优化判断。
- 国外:Apache Doris 4.x:Performance Tuning Process Guide:采用分区、连接计划、物化视图及 Profile 部分,补充分析型大查询应如何定位扫描和跨节点执行成本。




