Mysql join大表优化案例

2023-11-15

一、准备知识(Mysql join原理及结论)

1、MySQL join分为

  • inner join
  • left (outer) join
  • right (outer) join
  • full join(mysql不支持full join,但是可以利用left join + union + right join实现full join)
  • cross join(笛卡尔积),实际上inner join不指定on即和cross join表现一样
  • straight_join(效果等同于inner join,只是固定了驱动表顺序)

2、驱动表与被驱动表

  • inner join:由执行器自行决定谁是驱动表,谁是被驱动表
  • left join:左表是驱动表,右表是被驱动表
  • right join:右表是驱动表,左表是被驱动表
  • straight_join:固定左边为驱动表,右边为被驱动表

3、join执行流程

每取驱动表一行数据,去和被驱动表匹配。可以理解为双层for循环
所以数据量的时候,循环次数变多,这也是join性能问题的根源。

4、join执行的实现原理

  • Nest Loop Join (NLJ),就是单纯双层循环
  • Block Nest Loop Join (BNLJ),在NLJ基础上,利用join_buffer,一次取出一批驱动表数据,可以减少循环匹配次数
  • Index Nest Loop Join (INLJ),在NLJ基础上,利用被驱动表连接字段的索引直接找到匹配数据,可以减少循环次数

5、join on

  • on后跟连接条件,一般必须指定,且只对被驱动表有效(即即使对驱动表加了过滤条件该条件也无效)
  • 由此可知join on之后,驱动表包含全部数据,被驱动表只包含on条件过滤后的数据

6、on和where

  • on在join时就会过滤数据,而where是join完成后再对数据进行过滤,所以on比where先作用
  • 所以理论上过滤条件放在on后,比放在where后性能好
  • 但是过滤条件放在on后和where后,结果可能不一样(原因就在于on后条件只对被驱动表有效),所以谨慎在on后加驱动表的过滤条件
  • 针对inner join,on和where无啥差别

根据前面的说明,以下属于结论性说明

7、加过滤条件要想清楚

是先对被驱动表进行过滤还是join完再对驱动表和被驱动表进行过滤

8、尽量小表驱动大表

这里针对的是left join和right join,因为inner join会自动选择

9、被驱动表连接字段要加索引

否则Mysql就会使用Block Nest Loop Join,影响性能

10、explain命令分析出的第一行的表即是驱动表

11、优化join的思路

  • 顺着减少join时驱动表匹配被驱动表时的循环查找次数进行思考(想一下哪些结论是针对这个思路的?)
  • 如果join后的数据量很大,且还要进行相关聚合操作,可以考虑先聚合出临时表,再join(本案例就是这个思路)

二、案例

1、原sql

EXPLAIN
select camf.asset_management_id
from crm_asset_management_friend camf  INNER JOIN crm_asset_management cam ON camf.asset_management_id=cam.id
where camf.`status`=1
	 and cam.wx_status != 0
group by camf.asset_management_id having count(camf.id) > 10;
  • 用时:1.5s
  • explain结果:在这里插入图片描述

2、分析

  • cam数据量4000多,且基本不会再大量增加;camf数据量接近400万,且持续稳定增加ing
  • camf在asset_management_id上有索引
  • join完之后有320万数据(表明每一条驱动表cam数据匹配被驱动表camf循环次数很多(1条匹配几千条)),如下sql,再进行groupby,性能可想而知
select camf.asset_management_id
from crm_asset_management_friend camf  INNER JOIN crm_asset_management cam ON camf.asset_management_id=cam.id
where camf.`status`=1
	 and cam.wx_status != 0

3、新sql

EXPLAIN			
select cam.id from (		
select camf.asset_management_id
    from 
    crm_asset_management_friend camf  
    where camf.`status`=1
    	group by camf.asset_management_id having count(camf.id) > 10
    ) tmp INNER JOIN crm_asset_management cam ON tmp.asset_management_id=cam.id
where  cam.wx_status!=0;
  • 用时:1.0s
  • explain结果:
    在这里插入图片描述

4、结语

  • 之所以还是在1s以上,是因为本身如下groupby就耗时0.9s多
select camf.asset_management_id
from 
crm_asset_management_friend camf  
where camf.`status`=1
group by camf.asset_management_id having count(camf.id) > 10
  • 限于业务,表结构,也只能优化到这儿了。
  • 要想彻底优化,是需要提取出每个asset_management的count(camf.id)作为一个新字段维护到cam表(维护比较麻烦,这也是没有维护的原因)。这样查询friend数大于10的资产就不需要绕这样一大圈了。sql就会变为类似:
select cam.id from crm_asset_management cam
where  cam.wx_status!=0 and friendCount>10

这速度就会杠杆的了!!!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mysql join大表优化案例 的相关文章

  • Google Cloud SQL 在重新启动时卡住

    我的云 sql 实例长时间处于重新启动状态 在操作窗格中 重新启动的状态显示为待处理 并且还发生了导出 其状态仍为Running 有没有办法可以强制重新启动或取消重新启动或从常规备份中恢复数据 不 没有办法 如果您向 Google 支付高级
  • 即使没有结果也返回一个值

    我有这种简单的查询 它返回给定 id 的非空整数字段 SELECT field1 FROM table WHERE id 123 LIMIT 1 问题是如果找不到 id 结果集就是空的 我需要查询始终返回一个值 即使没有结果 我有这个东西工
  • PHP MySql 百分比

    我的问题是关于百分比 我不是专家 所以我会尽力以更好的方式进行解释 我的 mysql 服务器中有一个表 假设有 700 条记录 如下所示 Name country language Birth Lucy UK EN 1980 Mari Ca
  • 将庞大数据库从亚马逊RDS导出到本地mysql

    我在 Amazon RDS 上有一个 mysql 数据库 大约 600GB 数据 我需要将其移回本地专用服务器 但我不知道从哪里开始 每次我尝试初始化 sqldump 时它都会冻结 有没有办法将其移至 S3 甚至可能在开始下载之前将其分成更
  • PHP MySQL 使用选项/选择 HTML 表单标签进行多重搜索查询

    我正在尝试使用两个搜索字段设置基本的 MySQL LIKE 搜索 我不想拥有它 所以它有多个可选搜索字段 例如if isset POST city isset POST name 我不知道如何用 HTML 来做到这一点
  • 如何通过Elasticsearch模糊匹配电子邮件或电话?

    我想通过 Elasticsearch 对电子邮件或电话进行模糊匹配 例如 匹配所有以以下结尾的电子邮件 gmail com or 匹配所有电话开头136 我知道我可以使用通配符 query wildcard email gmail com
  • MySQL 与日语字符

    我试图弄清楚如何创建一个表 以便我可以在其中插入日语名字 现在我有 Type InnoDB Encoding UTF 8 Unicode utf8 Collation utf8 general ci 但是 当我插入字符时 它显示为 当我使用
  • mysql自动存储记录创建时间戳

    mysql 有什么方法可以在创建记录时自动将时间戳存储在记录行中 我试图使用时间戳 数据类型 和 current timestamp 作为默认值 但后来意识到每次更新记录时都会更新 我只需要一些可以存储创建时间戳的东西 Thanks Set
  • 学说迁移后备

    我们正在使用原则迁移 当迁移包含多个操作并且其中一个操作失败时 通常会出现问题 例如 如果迁移添加了 5 个外键 其中第 5 个失败 而字段长度不同 则修复字段错误并重新生成迁移不会not修复整个问题 而现在出现一个与 4 个密钥已存在有关
  • PHP 与 MySQL 查询性能( if 、 函数 )

    我只看到这个artice http www onextrapixel com 2010 06 23 mysql has functions part 5 php vs mysql performance 我需要知道在这种情况下什么是最好的表
  • 通过触发器应用表的列权限

    现在 我有一个名为 Members 的表 其中包含内容 分为联系人数据 银行数据 现在 管理员应该能够创建 更新 删除用户 这些用户保存在另一个表中 该表只能访问管理员 用户应该获得自己的 mysql 用户帐户 管理员还应该能够设置权限 例
  • 基于mysql表中唯一电子邮件地址的唯一代码?

    我有一个 mysql 表 它将存储用户电子邮件地址 每个地址都是唯一的 并且是主字段 和时间戳 我添加了另一列名为 unique code varchar 64 utf8 unicode ci 我非常感谢您提供的帮助 a 生成5位字母数字代
  • 如何在 MySQL 查询本身中检索 JSON 数组中存储的值?

    我有下表 product id product name image path misc 1 flex http firstpl course level id 19 group id 40067 2 Android http firstp
  • MySql如何将varchar(纬度,经度)转换为十进制字段?

    在 mysql 中 我有一个 varchar 其中包含 Google 地图提供的纬度和经度 我需要能够基于边界框值进行查询 但不需要现在可用的地理特征 我正在尝试使用 varchar 中找到的 Decimal 值填充 2 个新的 Decim
  • 加载“mysql2”Active Record 适配器时出错

    我正在尝试升级我的应用程序 这是我在部署应用程序时遇到的错误 加载 mysql2 Active Record 适配器时出错 缺少它所依赖的宝石 无法激活mysql2 0 4 4 已经激活mysql2 0 3 21 确保所有依赖项都添加到 G
  • 通过sequelize.query() 插入原始查询时不会触发挂钩

    我有以下内容EmployeeMySQL 数据库模型 var bcrypt require bcrypt module exports sequelize DataTypes gt const Employee sequelize defin
  • 如何从表中选择所有偶数 id?

    我想从 MySQL 数据库的表中选择所有甚至帖子 ID 然后显示它们 我还想获取所有带有奇怪 id 的帖子并将它们显示在其他地方 我想使用 PHP 来完成此操作 因为这是我使用的服务器端语言 或者 我是否必须选择所有帖子 然后使用 Java
  • 如何使用 Connector/C++ 更新 MySQL 中的一行值

    我有一个简单的数据库 想要更新一个 int 值 我最初执行一个查询并返回一个 ResultSet sql ResultSet 对于结果集中的每个条目 我想修改表的一个特定列中的值 然后将其写回到数据库 更新该行中的该条目 根据文档 我不清楚
  • 如何使用java避免Mysql数据库中的“数据因列被截断”?

    在我的 Java 程序中 Hibernate Bean 类定义一列 例如 TimtableVO java Column name REPEAT DAYS private WeekdayType repeatDays hear Weekday
  • 将redis数据移至MySQL的更快方法

    我们拥有庞大的购物和产品交易系统 我们在 MySQL 方面遇到了很多问题 因此经过几次研发后 我们计划使用 Redis 并开始将 Redis 集成到我们的系统中 继之前直接访问数据库之后 现在我们已经移动了Redis系统 用户购物车详情 关

随机推荐

  • 9、区块链简介

    区块链 Blockchain 在2008年由署名为中本聪的作者在 比特币 一种点对点的电子现金系统 一文提出 指的是一种在对等网络环境下 通过透明和可信规则 构建防伪造 防篡改和可追溯的块链式数据结构 实现和管理事务处理的模式 区块链本质上
  • 【译】IPSEC.CONF(5) - IPsec配置

    NAME ipsec conf IPsec配置 DESCRIPTION ipsec conf指定了Openswan IPsec子系统的大多数配置和控制信息 include ipsec conf 包含指定的配置文件 CONN SECTIONS
  • 【使用 flink-cdc 将数据从 mysql 同时同步到 redis, elastisearch, clickhouse】

    要从 MySQL 同时同步到 Redis Elasticsearch 和 Clickhouse 可以使用 Flink CDC 和 Flink Table API 来实现 首先 需要在 Flink 中配置 CDC 数据源 使其能够连接到 My
  • WIndows10系统 安装Anaconda、Pycharm以及在其中导入Pytorch环境(NVIDIA GPU版本)

    WIndows10系统 安装Anaconda Pycharm以及在其中导入Pytorch环境 NVIDIA GPU版本 1 判断电脑是否具有GPU 2 安装Anaconda 3 创建虚拟环境 3 1 利用conda命令创建虚拟环境 4 GP
  • MySQL——卸载重装MySQL失败?

    该问题通常是因为MySQL卸载时 没有完全清除相关信息导致的 解决办法是 把以前的安装目录删除 如果之前安装并未单独指定过服务安装目录 则默认安装目录是 C Program Files MySQL 彻底删除该目录 同时删除MySQL的Dat
  • [QT_024]Qt学习之QByteArray详解

    本文转自 Qt编程指南 作者 奇先生 Qt编程指南 Qt新手教程 Qt Programming Guide 本节学习 QByteArray 的两种用法 第一种作为字符串处理类 类似 QString 但 QByteArray 内部字符编码不确
  • 时间序列预测方法最全总结!

    时间序列预测就是利用过去一段时间的数据来预测未来一段时间内的信息 包括连续型预测 数值预测 范围估计 与离散型预测 事件预测 等 具有非常高的商业价值 需要明确一点的是 与回归分析预测模型不同 时间序列模型依赖于数值在时间上的先后顺序 同样
  • 一文讲透CRC校验码-附赠C语言实例

    一口君最近工作用到CRC校验 顺便整理本篇文章和大家一起研究 一 CRC概念 1 什么是CRC CRC Cyclic Redundancy Checksum 是一种纠错技术 代表循环冗余校验和 数据通信领域中最常用的一种差错校验码 其信息字
  • spark Scala中dataframe的常用关键字:withColumn

    withColumn关键字 用于操作dataframe原表某一列的数据 将操作完的每一行数据形成一列 用来替换一个表原有的列或者在原表后面追加新的列 语法如下 def withColumn colName String col Column
  • 家具商城小程序:连接优质家居产品的桥梁

    随着人们对家居生活品质的追求 家具商城小程序成为提供便捷购物和个性化服务的不可或缺的工具 通过家具商城小程序 用户可以浏览并购买各类家具产品 如沙发 床 桌子等 同时 家具商城小程序还提供个性化的推荐 客户评价和在线客服等功能 家具商城小程
  • JMeter性能测试,完整入门篇

    1 Jmeter简介 Apache JMeter是一款纯java编写负载功能测试和性能测试开源工具软件 相比Loadrunner而言 JMeter小巧轻便且免费 逐渐成为了主流的性能测试工具 是每个测试人员都必须要掌握的工具之一 本文为JM
  • 【Vue入门】语法 —— 事件处理器、自定义组件、组件通信

    目录 一 事件处理器 1 1 样式绑定 1 2 事件修饰符 1 3 按键修饰符 1 4 常用控制符 1 4 1 常用字符综合案例 1 4 2 修饰符 二 自定义组件 2 1 组件介绍及定义 2 2 组件通信 2 2 1 组件传参 父 gt
  • vim 操作命令大全

    曾经使用了两年多的Vim 手册也翻过一遍 虽然现在不怎么用vim了 曾经的笔记还是贴出来 与喜欢vim的朋友分享 1 关于Vim vim是我最喜欢的编辑器 也是Linux下第二强大的编辑器 虽然emacs是公认的世界第一 我认为使用emac
  • Job for named.service failed because the control process exited with error code.怎么解决

    问题 root localhost systemctl restart named Job for named service failed because the control process exited with error cod
  • 中台战略-第一章、企业数字化转型

    第一章 企业数字化转型 数字经济是当前所有企业在时代都要考虑的问题 不久的将来 他会成为社会经济中的新引擎 也会逐步推动产业互联和企业商业生态的数字化转型 消费者对于产品与服务的升级需求带动着各类触点场景和产品延伸服务的不断变化 云计算 大
  • npm run serve 卡住解决方案

    问题描述 在本地开发vue前端时 使用npm run serve运行vue项目 却运行到40 左右不动 删除node modules依赖包目录 重新npm install 但还是未解决 解决方案 并不是依赖包的问题 而是代码的原因 在vue
  • QNAP 安装nextcloud私有网盘

    下载nextcloud服务端 并上传到web文件夹下 首先安装并开启PHPmyadmin 在app store搜索并下载PHPmyadmin 同时 打开自带的mariadb服务 默认用户名密码就是qnap自己的用户名和密码 也可以更改 然后
  • 设计模式:高性能IO之Reactor模式

    讲到高性能IO绕不开Reactor模式 它是大多数IO相关组件如Netty Redis在使用的IO模式 为什么需要这种模式 它是如何设计来解决高性能并发的呢 最最原始的网络编程思路就是服务器用一个while循环 不断监听端口是否有新的套接字
  • 1. TypeScript 基础类型

    TypeScript 基础类型 1 布尔 数字 字符串类型 let myname string 小米 let age number 18 let bool boolean true console log 1 布尔 数字 字符串类型 myn
  • Mysql join大表优化案例

    一 准备知识 Mysql join原理及结论 1 MySQL join分为 inner join left outer join right outer join full join mysql不支持full join 但是可以利用left