故障分析 | MySQL 派生表优化
来到golang学习网的大家,相信都是编程学习爱好者,希望在这里学习数据库相关编程知识。下面本篇文章就来带大家聊聊《故障分析 | MySQL 派生表优化》,介绍一下MySQL,希望对大家的知识积累有所帮助,助力实战开发!
作者:xuty
一、问题 SQL
原 SQL 如下:
select name,count(name) from bm_id a left JOIN (select TaskName from up_pro_accept_v3_bdc union all select TaskName from up_pro_accept_v3_hsjs union all select TaskName from up_pro_accept_v3_hszjj union all select TaskName from up_pro_accept_v3_hzl union all select TaskName from up_pro_accept_v3_kjyw union all select TaskName from up_pro_accept_v3_kpzzzxwx union all select TaskName from up_pro_accept_v3_qdzc union all select TaskName from up_pro_accept_v3_rsj union all select TaskName from up_pro_accept_v3_sjba union all select TaskName from up_pro_accept_v3_spk union all select TaskName from up_pro_accept_v3_test union all select TaskName from up_pro_accept_v3_wygl union all select TaskName from up_pro_accept_v3_yms union all select TaskName from up_pro_accept_v3_zjj union all select TaskName from up_pro_accept_v3w) t on a.zxi = t.TaskName group by name
这是一个统计类的 SQL,直接执行跑了好几个小时都没有结束,所以暂时不知道实际耗时,因为实在是太久了~
二、执行计划
老步骤,我们先看下执行计划,如下图:

这里 SQL 执行主要分为 2 个步骤:
-
顺序扫描每个
select * from (select * from up_pro_accept_v3_bdc) a where a.rowguid = '185c44aa-c23f-4e6f-bcd2-a38df16e2cc3'
四、SQL 优化
简单介绍了下派生表,下面我们开始尝试优化这个 SQL,步骤分 2 步:
- 解决多张派生子表
/* 改写后 SQL */ SELECT NAME ,count(NAME) FROM ( SELECT NAME FROM bm_id LEFT JOIN up_pro_accept_v3_bdc bdc ON bm_id.zxi = bdc.TaskName UNION ALL SELECT NAME FROM bm_id LEFT JOIN up_pro_accept_v3_hsjs hsjs ON bm_id.zxi = hsjs.TaskName UNION ALL SELECT NAME FROM bm_id LEFT JOIN up_pro_accept_v3_hszjj hszjj ON bm_id.zxi = hszjj.TaskName UNION ALL SELECT NAME FROM bm_id LEFT JOIN up_pro_accept_v3_hzl hzl ON bm_id.zxi = hzl.TaskName UNION ALL SELECT NAME FROM bm_id LEFT JOIN up_pro_accept_v3_kjyw kjyw ON bm_id.zxi = kjyw.TaskName UNION ALL SELECT NAME FROM bm_id LEFT JOIN up_pro_accept_v3_kpzzzxwx kp ON bm_id.zxi = kp.TaskName UNION ALL SELECT NAME FROM bm_id LEFT JOIN up_pro_accept_v3_qdzc qdzc ON bm_id.zxi = qdzc.TaskName UNION ALL SELECT NAME FROM bm_id LEFT JOIN up_pro_accept_v3_rsj rsj ON bm_id.zxi = rsj.TaskName UNION ALL SELECT NAME FROM bm_id LEFT JOIN up_pro_accept_v3_sjba sjba ON bm_id.zxi = sjba.TaskName UNION ALL SELECT NAME FROM bm_id LEFT JOIN up_pro_accept_v3_spk spk ON bm_id.zxi = spk.TaskName UNION ALL SELECT NAME FROM bm_id LEFT JOIN up_pro_accept_v3_test test ON bm_id.zxi = test.TaskName UNION ALL SELECT NAME FROM bm_id LEFT JOIN up_pro_accept_v3_wygl wygl ON bm_id.zxi = wygl.TaskName UNION ALL SELECT NAME FROM bm_id LEFT JOIN up_pro_accept_v3_yms yms ON bm_id.zxi = yms.TaskName UNION ALL SELECT NAME FROM bm_id LEFT JOIN up_pro_accept_v3_zjj zjj ON bm_id.zxi = zjj.TaskName UNION ALL SELECT NAME FROM bm_id LEFT JOIN up_pro_accept_v3w v3w ON bm_id.zxi = v3w.TaskName ) t GROUP BY t.name
再来看下改写后的 SQL 执行计划,发现确实如我们预想的,在子查询中可以通过索引来进行表关联(
CREATE TABLE `tmp_up` ( `taskname` varchar(500) DEFAULT NULL, KEY `idx_taskname` (`taskname`));
- 将子查询结果插入至临时表
insert into tmp_up select taskname from up_pro_accept_v3_bdc union all select taskname up_pro_accept_v3_hsjs ......
- 使用临时表代替子查询
select name,count(name) from bm_id a left JOIN (select TaskName from tmp_up )t on a.zxi = t.TaskName group by name
- 对比下查询结果是否一致
惊讶的发现改写 SQL 的结果集会多出来很多?这里可以确认走临时表的结果集是肯定没问题的,那么问题肯定出在改写 SQL 上!
回头再仔细想一下,结合小测试,发现这样改写 SQL 确实会改变语义,问题主要是出在
LEFT JOIN
,原本 bm_id 只作了一次表关联
,而改写 SQL 后,要做多次表关联
,导致最后的结果集会多出来一部分因为LEFT JOIN
而产生的重复数据。如果是
INNER JOIN
,其实就不会产生重复数据,我们也测试下,结果确实如所想,内联是没问题的~六、个人总结
这次 SQL 优化案例个人感觉是比较有难度的,很多点自己一开始也没有想到。就比如 SQL 改写,一开始以为是没有语义上的区别,直到做了测试才知道,所以啊,很多时候不能盲目自信啊。
针对这个 SQL 来说,想要直接通过改写 SQL 优化还是比较难的,当然这里说的是不改变语义的情况下,我暂时没有想到好的改写方式,也许是火候还不够。
解决方式总结有 2 个:
- 用
内联
替代左联
,然后使用上述的改写 SQL,优点是比较方便且查询速度较快
,但是结果集会变化
。 - 通过
临时表
代替子查询
,缺点是比较繁琐,需要多个步骤实现
,优点是速度也较快
且结果集不会变化
。
附录:
http://mysql.taobao.org/month...
https://blog.csdn.net/sun_ash...
https://imysql.com/node/103
https://dev.mysql.com/doc/ref...今天关于《故障分析 | MySQL 派生表优化》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!
- 解决多张派生子表

- 上一篇
- 使用PyMysql调用Mysql数据库示例

- 下一篇
- 协助报表开发之 MongoDB join mysql
-
- 欢呼的手机
- 这篇文章真是及时雨啊,太全面了,很棒,码住,关注师傅了!希望师傅能多写数据库相关的文章。
- 2023-04-09 14:24:08
-
- 高大的台灯
- 很棒,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,看完之后很有帮助,总算是懂了,感谢作者分享技术贴!
- 2023-03-24 00:14:46
-
- 数据库 · MySQL | 1天前 |
- 如何检测电脑是否安装MySQL的5种方法
- 278浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL分区表查询优化技巧
- 126浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL建库语句与字符集设置教程
- 414浏览 收藏
-
- 数据库 · MySQL | 2天前 |
- MySQL中AS别名用法详解
- 320浏览 收藏
-
- 数据库 · MySQL | 2天前 |
- MySQL创建带主键的表实例
- 247浏览 收藏
-
- 数据库 · MySQL | 3天前 |
- 主外键关系怎么建立?
- 149浏览 收藏
-
- 数据库 · MySQL | 3天前 |
- MySQL中IF函数使用详解
- 392浏览 收藏
-
- 数据库 · MySQL | 4天前 |
- MySQL中IF函数使用详解
- 268浏览 收藏
-
- 数据库 · MySQL | 4天前 |
- MySQL入门:核心概念与操作全解析
- 162浏览 收藏
-
- 数据库 · MySQL | 4天前 |
- MySQL事务是什么?如何保证数据一致性?
- 349浏览 收藏
-
- 数据库 · MySQL | 5天前 |
- MySQL数据分片实现方法及常见方案解析
- 363浏览 收藏
-
- 数据库 · MySQL | 5天前 |
- MySQL基础:增删改查全教程
- 345浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 514次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 499次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- AI Mermaid流程图
- SEO AI Mermaid 流程图工具:基于 Mermaid 语法,AI 辅助,自然语言生成流程图,提升可视化创作效率,适用于开发者、产品经理、教育工作者。
- 702次使用
-
- 搜获客【笔记生成器】
- 搜获客笔记生成器,国内首个聚焦小红书医美垂类的AI文案工具。1500万爆款文案库,行业专属算法,助您高效创作合规、引流的医美笔记,提升运营效率,引爆小红书流量!
- 713次使用
-
- iTerms
- iTerms是一款专业的一站式法律AI工作台,提供AI合同审查、AI合同起草及AI法律问答服务。通过智能问答、深度思考与联网检索,助您高效检索法律法规与司法判例,告别传统模板,实现合同一键起草与在线编辑,大幅提升法律事务处理效率。
- 735次使用
-
- TokenPony
- TokenPony是讯盟科技旗下的AI大模型聚合API平台。通过统一接口接入DeepSeek、Kimi、Qwen等主流模型,支持1024K超长上下文,实现零配置、免部署、极速响应与高性价比的AI应用开发,助力专业用户轻松构建智能服务。
- 799次使用
-
- 迅捷AIPPT
- 迅捷AIPPT是一款高效AI智能PPT生成软件,一键智能生成精美演示文稿。内置海量专业模板、多样风格,支持自定义大纲,助您轻松制作高质量PPT,大幅节省时间。
- 690次使用
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- 搞一个自娱自乐的博客(二) 架构搭建
- 2023-02-16 244浏览
-
- B-Tree、B+Tree以及B-link Tree
- 2023-01-19 235浏览
-
- mysql面试题
- 2023-01-17 157浏览
-
- MySQL数据表简单查询
- 2023-01-10 101浏览