SQL优化--关联子查询的前世今生

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: SQL优化--关联子查询的前世今生

一、发现SQL问题



还是先从发现问题说起,笔者在处理数据时,写了一个嵌套的sql,类似如下(这里是简化了,原sql是多层嵌套的in查询,原理一样):


update  room_relation
  set cus_phone = '18222311909'
where room_id in 
(
select id from room where room_name = '101'
)


当时sql执行了30+分钟依然没有执行完毕,当时就蒙了,怎么会这么慢,因为按照括号内的条件筛选的话其实只有几条数据,应该是毫秒级就会执行完毕的。然后就用explain查看了执行计划,发现主表竟然是基本全表扫描,当时表里大概有700w数据左右。问题就是这样。


二、关联子查询慢的根本原因



上面这个update语句之所以出问题(超级慢),关键在于使用了in和关联子查询,为什么用了这个sql就这么慢呢,其实和mysql的执行优化器有关,mysql的执行优化器并没有按我们想的那样,先执行括号内的内容,再执行外层查询,实际删恰恰相反,先执行了外层sql再执行的子查询,下面给出《高性能MySql》这本书的官方解释。


1.查阅资料


下面这一段是《高性能MySql》中6.5.1这一节给上面的现象作出的解释:


7323671a68594fffacd91f316d65e6a8.png

e61c650879c841d699ed2f2044d3fcf8.png


上面电子书的版本比较老了是基于mysql5.5来讲的,其实mysql5.5以后对关联子查询做了优化,这点在最后一节我们一起对比下各个版本中关联子查询是如何被优化的。


2.总结


慢的原因总结就是我们使用了in(子查询) 的模式进行了数据筛选,这样会导致执行优化器将查询优化的更加复杂,从而导致了性能的急剧下降,优化的话我们只需要将子查询更改为inner join即可。比如笔者最初的sql更改成如下即可:

update  room_relation rel
inner join room ro on rel.room_id = ro.id and ro.room_name = '101'
set cus_phone = '18222311909'


三、MySql关联子查询优化的前世今生



上面我们已经知道了只要使用了in加上子查询那么这个sql就会非常慢,而这个问题到mysql5.6才被解决,这句话虽然是书上说的但是不全对,因为mysql5.6只对select中的子查询进行了优化,update中的子查询还是一样的糟糕。注意若是使用explain查看执行计划时查询类型出现了 dependent subquery,说明sql真正执行时有关联子查询,我们下面的验证主要是根据这个特征来判断的。下面从两个角度update、select来一起看下各个版本的mysql是的执行计划。下面所有环境的数据库、表等所有信息均一致。


所使用的update如下

explain 
update  room_relation
set cus_phone = '18222311909'
 where room_id in (
select id from room where room_name = '101'
)


所使用的select如下

explain 
select * from   room_relation
 where room_id in (
select id from room where room_name = '101'
)


1.Mysql5.5中的关联子查询


从下面两个图的执行结果我们可以看到mysql5.5select还是会有关联子查询的,但是执行计划不支持update这个有点坑,不过5.6时已经支持update的执行计划了。


1. select

82d2aca3b04144ba89922898e72858df.png


2. update


76ca73e1205a4b38a78336346dc84923.png


2.Mysql5.6中的关联子查询


msyql5.6开始支持update的执行计划,同时根据下图我们可以看到被优化器优化后的select已经不会有关联子查询出现了,但是update还是会有关联子查询。


1. select

fbf5d5a5602744a2b486655f2718447d.png


2. update

370b5bccab1949b1b80011dc7f24ba63.png


3.Mysql5.7中的关联子查询


从下面的结果我们可以看出,在这一块从5.6到5.7没有任何变化,我们继续往下看8.0版本


1. select

16f576448c604416abc8a77b9eee93a9.png


2. update


5cccd60103de436dbc0b3af851fbb1ca.png


4.Mysql8.0中的关联子查询


从下面的运行截图我们可以看出8.0时无论是select还是update,执行优化器都会把关联子查询优化掉。所以来说到mysql8.0优化器已经变得更加符合我们需要了。


1. select

d293af8e719347fc80d608419786ee4d.png


2. update

d34317100f364915a697a5b207f4a58b.png


四、总结



关联子查询会给我们的select或者update降低效率,但是这句话必须结合mysql版本来说,抛开版本聊这句话是没有意义的,从我们上面的实践来看,在mysql8.0之前更新语句里只要出现关联子查询(就是in+子查询)那么sql性能就会急剧下降(无论更新还是查询数据量较小时看不出来影响,必须数据量达到大几十万才能明显看到影响),在mysql5.6之前只要select语句中出现关联子查询也会使得查询性能骤降,鉴于目前主流的msyql版本还是5.6/5.7/8.0,所以说我们完全可以不考虑select的问题,只需要关注若是msyql不是8.0,就不要写关联子查询的语句了。


相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
11天前
|
SQL 关系型数据库 MySQL
MySQL进阶突击系列(07) 她气鼓鼓递来一条SQL | 怎么看执行计划、SQL怎么优化?
在日常研发工作当中,系统性能优化,从大的方面来看主要涉及基础平台优化、业务系统性能优化、数据库优化。面对数据库优化,除了DBA在集群性能、服务器调优需要投入精力,我们研发需要负责业务SQL执行优化。当业务数据量达到一定规模后,SQL执行效率可能就会出现瓶颈,影响系统业务响应。掌握如何判断SQL执行慢、以及如何分析SQL执行计划、优化SQL的技能,在工作中解决SQL性能问题显得非常关键。
|
20天前
|
SQL Oracle 关系型数据库
如何在 Oracle 中配置和使用 SQL Profiles 来优化查询性能?
在 Oracle 数据库中,SQL Profiles 是优化查询性能的工具,通过提供额外统计信息帮助生成更有效的执行计划。配置和使用步骤包括:1. 启用自动 SQL 调优;2. 手动创建 SQL Profile,涉及收集、执行调优任务、查看报告及应用建议;3. 验证效果;4. 使用 `DBA_SQL_PROFILES` 视图管理 Profile。
|
2月前
|
SQL Oracle 数据库
使用访问指导(SQL Access Advisor)优化数据库业务负载
本文介绍了Oracle的SQL访问指导(SQL Access Advisor)的应用场景及其使用方法。访问指导通过分析给定的工作负载,提供索引、物化视图和分区等方面的优化建议,帮助DBA提升数据库性能。具体步骤包括创建访问指导任务、创建工作负载、连接工作负载至访问指导、设置任务参数、运行访问指导、查看和应用优化建议。访问指导不仅针对单条SQL语句,还能综合考虑多条SQL语句的优化效果,为DBA提供全面的决策支持。
95 11
|
1月前
|
SQL 分布式计算 Java
Spark SQL向量化执行引擎框架Gluten-Velox在AArch64使能和优化
本文摘自 Arm China的工程师顾煜祺关于“在 Arm 平台上使用 Native 算子库加速 Spark”的分享,主要内容包括以下四个部分: 1.技术背景 2.算子库构成 3.算子操作优化 4.未来工作
|
3月前
|
SQL 缓存 监控
大厂面试高频:4 大性能优化策略(数据库、SQL、JVM等)
本文详细解析了数据库、缓存、异步处理和Web性能优化四大策略,系统性能优化必知必备,大厂面试高频。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:4 大性能优化策略(数据库、SQL、JVM等)
|
3月前
|
SQL 缓存 数据库
SQL慢查询优化策略
在数据库管理和应用开发中,SQL查询的性能优化至关重要。慢查询优化不仅可以提高应用的响应速度,还能降低服务器负载,提升用户体验。本文将详细介绍针对SQL慢查询的优化策略。
|
3月前
|
SQL 存储 BI
gbase 8a 数据库 SQL合并类优化——不同数据统计周期合并为一条SQL语句
gbase 8a 数据库 SQL合并类优化——不同数据统计周期合并为一条SQL语句
|
3月前
|
SQL 数据库
gbase 8a 数据库 SQL优化案例-关联顺序优化
gbase 8a 数据库 SQL优化案例-关联顺序优化
|
3月前
|
SQL 数据库 UED
SQL性能提升秘籍:5步优化法与10个实战案例
在数据库管理和应用开发中,SQL查询的性能优化至关重要。高效的SQL查询不仅可以提高应用的响应速度,还能降低服务器负载,提升用户体验。本文将分享SQL优化的五大步骤和十个实战案例,帮助构建高效、稳定的数据库应用。
217 3
|
3月前
|
SQL 缓存 监控
SQL性能提升指南:五大优化策略与十个实战案例
在数据库性能优化的世界里,SQL优化是提升查询效率的关键。一个高效的SQL查询可以显著减少数据库的负载,提高应用响应速度,甚至影响整个系统的稳定性和扩展性。本文将介绍SQL优化的五大步骤,并结合十个实战案例,为你提供一份详尽的性能提升指南。
86 0