Mysql中慢 SQL 优化实战:减少不必要的 JOIN 关联
Mysql中慢 SQL 优化实战减少不必要的 JOIN 关联一、问题背景线上接口查询收货单的出库物流信息时出现慢 SQL。该 SQL 通过三表 JOIN收货单主表 → 物流记录表 → 物流节点明细表查询物流轨迹数据其中收货单主表数据量超过 1200 万行。注博客https://blog.csdn.net/badao_liumang_qizhi二、优化流程1. 定位慢 SQL通过慢查询日志或 APM 监控系统获取到慢 SQL 的完整文本、执行时间和调用链路trace-id。2. 分析 SQL 结构原始 SQL 的执行结构receiving_goods_record (主表, 1200w) INNER JOIN store_receiving_logistics_record (物流记录表) LEFT JOIN store_receiving_logistics_record_item (物流节点明细表)3. 识别冗余 JOINsql 中直接可以从表中获取数据并且主表中的 record_code 字段是有索引的。分析发现 SELECT 中从主表取的字段record_code、order_code在物流记录表中同样存在且数据一致关联主表纯属冗余。4. 数据一致性验证通过 SQL 查询验证两表字段的数据一致性不一致记录数 0确认去掉 JOIN 不会导致数据差异。5. 修改并测试修改 Mapper XML去掉冗余 JOIN本地启动服务验证接口正常返回。三、核心技术点3.1 EXPLAIN 执行计划EXPLAINSELECT...FROMtable_a aINNERJOINtable_b bONa.idb.a_idWHEREa.codexxx;关键指标字段含义关注点type访问类型ALL(全表扫描) → ref(索引) → const(常量)key实际使用的索引NULL 表示未走索引rows预估扫描行数数值越小越好Extra额外信息Using filesort / Using temporary 需关注3.2 索引命中原则-- 单列索引WHERE 条件精确匹配时命中CREATEINDEXidx_record_codeONlogistics_record(record_code);SELECT*FROMlogistics_recordWHERErecord_codexxx;-- 命中-- 联合索引遵循最左前缀原则CREATEINDEXidx_member_codeONlogistics_record(member_id,order_code);SELECT*FROMlogistics_recordWHEREmember_id1;-- 命中SELECT*FROMlogistics_recordWHEREmember_id1ANDorder_codex;-- 命中SELECT*FROMlogistics_recordWHEREorder_codex;-- 不命中3.3 JOIN 的代价每增加一个 JOINMySQL 需要根据驱动表的结果集逐行去被驱动表查找匹配行如果被驱动表没有合适索引会产生全表扫描结果集膨胀 → 内存消耗增大 → 排序代价增大四、优化原理4.1 减少 JOIN 表数量这是本次优化的核心原理。当你发现SELECT 中从 A 表取的字段在 B 表中也有相同的数据冗余存储/数据同步字段就可以去掉对 A 表的关联直接从 B 表取字段。优化前三表SELECTa.name,b.detail,c.itemFROMbig_table a-- 1000w 行INNERJOINmedium_table bONa.idb.a_idLEFTJOINsmall_table cONb.idc.b_idWHEREa.codexxx;优化后两表SELECTb.name,b.detail,c.item-- name 字段从 b 表直接取FROMmedium_table bLEFTJOINsmall_table cONb.idc.b_idWHEREb.codexxx;-- b 表的 code 有索引4.2 驱动表选择MySQL 的 JOIN 执行顺序由优化器决定但通常小表驱动大表性能更优WHERE 条件能快速过滤的表适合作为驱动表五、常见的慢 SQL 优化方案方案一消除冗余 JOIN本次使用适用场景JOIN 的表只是为了取几个字段而这些字段在其他已关联的表中也有。-- 优化前三表 JOIN 只为取 order 表的 order_noSELECTo.order_no,d.product_name,d.qtyFROMorders oINNERJOINorder_details dONo.idd.order_idWHEREo.id12345;-- 优化后order_details 表本身冗余存储了 order_noSELECTd.order_no,d.product_name,d.qtyFROMorder_details dWHEREd.order_id12345;方案二添加合适索引适用场景WHERE 条件或 JOIN 条件的字段没有索引。-- 慢查询order_code 无索引全表扫描SELECT*FROMshipment_detailWHEREmember_id1179109ANDorder_codeER.240418.000673;-- 添加联合索引CREATEINDEXidx_member_orderONshipment_detail(member_id,order_code);方案三改写子查询为 JOIN适用场景IN 子查询在大数据量下性能差。-- 优化前子查询SELECT*FROMordersWHEREcustomer_idIN(SELECTidFROMcustomersWHERElevelVIP);-- 优化后改写为 JOINSELECTo.*FROMorders oINNERJOINcustomers cONo.customer_idc.idWHEREc.levelVIP;方案四分页优化延迟关联适用场景深分页 LIMIT offset, size 越往后越慢。-- 优化前LIMIT 100000, 10 需要扫描 100010 行SELECT*FROMordersORDERBYidDESCLIMIT100000,10;-- 优化后先定位 ID 区间再取数据SELECT*FROMordersWHEREid(SELECTidFROMordersORDERBYidDESCLIMIT100000,1)ORDERBYidDESCLIMIT10;方案五大表数据归档适用场景因为某表数据越来越多导致执行 sql 越来越慢因为 sql 暂时无法优化所以先按照备份数据的方式处理把指定之间之前的数据全部备份到备份表中一年一张表。-- 按年归档将历史数据迁移到归档表INSERTINTOxxx_2025SELECT*FROMxxxWHEREaccount_time2026-01;DELETEFROMxxxWHEREaccount_time2026-01;-- 或使用 pt-archiver 等工具无锁归档方案六为大表新增索引Online DDL适用场景因为只使用创建时间查询数据所以需要增加无锁变更把 create_time 增加索引表数据共 5000w。-- MySQL 5.6 支持 Online DDL不阻塞 DMLALTERTABLEstore_inbound_masterADDINDEXidx_create_time(create_time),ALGORITHMINPLACE,LOCKNONE;-- 或使用 gh-ost / pt-online-schema-change 进行无锁变更六、优化效果评估维度优化前优化后JOIN 表数量3 表2 表驱动表数据量1200w (receiving_goods_record)470w (store_receiving_logistics_record)索引使用orm.record_code 走唯一索引后再 JOINsdlr.record_code 直接走索引网络/内存开销需传输主表行数据无冗余数据传输七、总结检查清单在遇到慢 SQL 时按以下顺序排查是否有不必要的 JOIN— 分析 SELECT 字段来源确认是否可以从已有表获取WHERE/JOIN 条件是否走索引— 用 EXPLAIN 确认必要时添加索引是否有子查询可改写— IN 子查询改为 JOIN结果集是否过大— 增加过滤条件、分页优化表数据量是否可以缩减— 历史数据归档、分表

相关新闻

AI记忆管理与企业知识库:巴别鸟感忆定位与智巢AI的演进路径

AI记忆管理与企业知识库:巴别鸟感忆定位与智巢AI的演进路径

AI记忆管理与企业知识库:巴别鸟感忆定位与智巢AI的演进路径 企业知识管理这些年经历了几个阶段,从最初的共享文件夹,到后来的网盘,再到带AI功能的智能网盘。每一次演进都对应着企业实际需求的深化。巴别鸟的产品定位也在这个过程中…

2026/8/11 0:32:17 阅读更多 →
为什么 RS-485 选型该多看国科安芯 ASM485S:从技术原理讲透

为什么 RS-485 选型该多看国科安芯 ASM485S:从技术原理讲透

RS-485 几乎是工业通信的代名词,可一旦把选型标准从"能通就行"抬到"十年不掉线、上得了星、进得了核岛",市面上的芯片就开始分层。本文以国科安芯 ASM485S 为例,从差分原理一路讲到辐射、温度、静电三道硬坎,…

2026/8/11 0:32:17 阅读更多 →
Vue3 全栈项目本地环境跑通指南:从 Node/pnpm 依赖冲突到 Vite 代理调优

Vue3 全栈项目本地环境跑通指南:从 Node/pnpm 依赖冲突到 Vite 代理调优

Vue3 全栈项目本地环境跑通指南:从 Node/pnpm 依赖冲突到 Vite 代理调优 拉下项目仓库执行 pnpm install,终端吐出一大堆红字报错。换了 Node.js 版本重新编译,原生 Node C 模块 node-gyp 又卡在构建步骤。好不容易启动了 dev server&#xf…

2026/8/11 0:32:17 阅读更多 →

最新新闻

电动汽车参与运行备用的能力评估及其仿真分析(Matlab代码实现)

电动汽车参与运行备用的能力评估及其仿真分析(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 &#x1f381…

2026/8/11 1:08:34 阅读更多 →
PCDN技术解析与运营商封杀动因

PCDN技术解析与运营商封杀动因

1. PCDN技术原理与市场现状解析 PCDN(Peer-to-Peer Content Delivery Network)本质上是一种利用终端用户设备作为边缘节点的分布式内容分发技术。与传统CDN依赖专业服务器集群不同,PCDN通过调度海量普通用户的闲置带宽和存储资源,…

2026/8/11 1:08:34 阅读更多 →
FTP跨系统文件传输:Windows与Ubuntu高效互传方案

FTP跨系统文件传输:Windows与Ubuntu高效互传方案

1. 为什么选择FTP进行跨系统文件传输?在企业IT环境和开发者工作流中,Windows与Linux系统间的文件交换是高频刚需。我经历过无数次用U盘来回拷贝的繁琐,也试过各种网盘同步的延迟问题,最终发现FTP(File Transfer Protoc…

2026/8/11 1:08:34 阅读更多 →
Linux共享内存原理与高性能编程实践

Linux共享内存原理与高性能编程实践

1. 共享内存的本质与价值当两个进程需要频繁交换数据时,传统的管道或消息队列每次传输都要经过内核态与用户态的切换,这种数据拷贝在性能敏感场景会成为瓶颈。而共享内存允许不同进程直接访问同一块物理内存区域,就像多个程序员在同一个办公室…

2026/8/11 1:08:34 阅读更多 →
LuaJIT字节码逆向实战:LJD工具原理与反编译技术详解

LuaJIT字节码逆向实战:LJD工具原理与反编译技术详解

1. 项目概述:当LuaJIT字节码成为“天书”如果你曾经尝试过逆向分析一个使用LuaJIT编译的应用,比如某些游戏或移动应用,那你大概率会面对一个令人头疼的局面:好不容易从资源包里提取出来的.lua文件,用文本编辑器打开一看…

2026/8/11 1:07:33 阅读更多 →
强弱电网适配场景下构网 - 跟网逆变器并联系统协同控制逻辑及暂态动态行为研究(Simulink仿真实现)

强弱电网适配场景下构网 - 跟网逆变器并联系统协同控制逻辑及暂态动态行为研究(Simulink仿真实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 &#x1f381…

2026/8/11 1:07:33 阅读更多 →

日新闻

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南 【免费下载链接】video2x A machine learning-based video super resolution and frame interpolation framework. Est. Hack the Valley II, 2018. 项目地址: https://gitcode.com/GitHub_Trending/vi/v…

2026/8/11 0:00:02 阅读更多 →
前后端分离项目中控制台与接口工具数据差异排查指南

前后端分离项目中控制台与接口工具数据差异排查指南

1. 问题现象解析:控制台与Apifox的数据差异 最近在调试一个前后端分离项目时,遇到了一个典型问题:后端服务在本地开发环境控制台能正常输出查询数据,但通过Apifox测试时却返回空结果。这种"控制台有数据,接口工具…

2026/8/11 0:00:03 阅读更多 →
AI编程实战:从Claude Code踩坑到游戏开发入门

AI编程实战:从Claude Code踩坑到游戏开发入门

1. 从“AI能帮我做游戏”到“AI让我重新学编程”最近身边不少朋友,尤其是一些非技术背景、但对游戏开发有浓厚兴趣的朋友,都在问我同一个问题:“听说现在用Claude Code这种AI编程工具,小白也能做游戏了,是真的吗&#…

2026/8/11 0:00:03 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/11 1:08:05 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/11 1:08:05 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/11 1:08:05 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/10 17:07:33 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/11 1:08:06 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/10 17:07:33 阅读更多 →