MySQL一次Join表的性能优化分析,性能相差上千倍

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 在某技术群里有人发了两条sql,问为什么性能有这么大的差距,下面是当时的问题

背景

在某技术群里有人发了两条sql,问为什么性能有这么大的差距,下面是当时的问题

线索

SQL 1

SELECT*FROM T1 LEFT JOIN T2 ON T1.f1= T2.f1AND T2.f2ISNULLWHERE T1.f1='2875205';

explain

SQL 2

SELECT*FROM T1 LEFT JOIN T2 ON T1.f1= T2.f1WHERE T1.f1='2875205'AND T2.f2ISNULL;

explain

提问:T1.f1,T2.f1,T2.f2都有索引,T1表大约3万行,T2表大约100万行(T2.f2字段90%是null),这两条sql的结果集是一模一样的,为什么第一条sql要3秒,第二条sql只有1毫秒?

分析

性能分析很多情况下看explain能看出很多问题,我们首先看一下两条sql的explain,首先都是使用T1.f1的idx_f1索引,type是ref,row是1·,可以先忽略,着重看第二行

sql1:

因为join条件里有T2.f2 is null,所以选择了T2.f2的索引idx_f2,扫描行数是1+1*90w,就是说T1每匹配一行,都需要扫描T2的90%的行,虽然被驱动表走了索引,但又不完全走,约等于BNL算法被驱动表全表扫描

sql2:

T1.f1 = T2.f1选择了T2.f1的索引idx_f1,扫描行数是1+n(因为群友没提供满足条件说里面有多少行满足,但必定远小于90w)且是索引查询

扩展知识

MySQL JOIN算法

Nested-Loop Join Algorithm(NLJ)

  • 从驱动表取符合条件的一行
  • 根据驱动表的数据查询被驱动表
  • 返回符合条件的数据为结果集

整个过程类似于嵌套循环

https://dev.mysql.com/doc/refman/8.0/en/nested-loop-joins.html#nested-loop-join-algorithm

Block Nested-Loop Join Algorithm(BNL)

  • 查询驱动表的数据写到join_buffer(join_buffer_size确定大小),写不下就分批执行以下操作
  • 查询被驱动表的数据匹配join_buffer
  • 返回符合条件的数据为结果集

https://dev.mysql.com/doc/refman/8.0/en/nested-loop-joins.html#block-nested-loop-join-algorithm

Hash Join Optimization

MySQL 8.0.18新增的算法,具体类似BNL,并且删除了BNL算法,只是会将join_buffer的数据转成散列表存储

  • 查询驱动表的数据写到join_buffer(join_buffer_size确定大小)存储成散列表,写不下就分批执行以下操作
  • 查询被驱动表的数据匹配join_buffer,因为是散列表,所以时间复杂度是O(1)
  • 返回符合条件的数据为结果集

https://dev.mysql.com/doc/refman/8.0/en/hash-joins.html

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
7天前
|
存储 缓存 负载均衡
mysql的性能优化
在数据库设计中,应选择合适的存储引擎(如MyISAM或InnoDB)、字段类型(如char、varchar、tinyint),并遵循范式(1NF、2NF、3NF)。功能上,可以通过索引优化、缓存和分库分表来提升性能。架构上,采用主从复制、读写分离和负载均衡可进一步提高系统稳定性和扩展性。
27 9
|
14天前
|
缓存 监控 关系型数据库
如何根据监控结果调整 MySQL 数据库的参数以提高性能?
【10月更文挑战第28天】根据MySQL数据库的监控结果来调整参数以提高性能,需要综合考虑多个方面的因素
54 1
|
14天前
|
监控 关系型数据库 MySQL
如何监控和诊断 MySQL 数据库的性能问题?
【10月更文挑战第28天】监控和诊断MySQL数据库的性能问题是确保数据库高效稳定运行的关键
31 1
|
14天前
|
缓存 关系型数据库 MySQL
如何优化 MySQL 数据库的性能?
【10月更文挑战第28天】
38 1
|
15天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
81 1
|
24天前
|
存储 关系型数据库 MySQL
基于案例分析 MySQL 权限认证中的具体优先原则
【10月更文挑战第26天】本文通过具体案例分析了MySQL权限认证中的优先原则,包括全局权限、数据库级别权限和表级别权限的设置与优先级。全局权限优先于数据库级别权限,后者又优先于表级别权限。在权限冲突时,更严格的权限将被优先执行,确保数据库的安全性与资源合理分配。
|
16天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
47 0
|
25天前
|
存储 监控 关系型数据库
MySQL并发控制与管理:优化数据库性能的关键
【10月更文挑战第17天】MySQL并发控制与管理:优化数据库性能的关键
108 0
|
8天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
23 4
|
6天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
20 1