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大表优化案例 的相关文章

  • MySQL如何连接两个字段的表

    我有两张桌子date and id字段 我想加入这两个领域 我试过 JOIN t2 ON CONCAT t1 id t1 date CONCAT t2 id t2 date 这有效 但速度非常慢 有一个更好的方法吗 JOIN t2 ON t
  • 插入前检查数据库中是否存在行

    DBH new PDO dsn username password opt DBH gt setAttribute PDO ATTR ERRMODE PDO ERRMODE EXCEPTION DBH gt setAttribute PDO
  • 我如何从mysql获取上周、本周和上个月的记录

    我在 Codeigniter 中以 strtotime 格式存储日期 一周从周日开始 this gt db gt where this gt weight create date lt curdate INTERVAL DAYOFWEEK
  • Laravel 4 中如何知道查询是否失败?

    我将 Laravel 4 与 MySQL 结合使用 我想知道如何控制在数据库中插入 更新或删除记录时可能出现的错误 例如 如果我进行如下更新 DB table user gt where id id gt update userdata 我
  • 从 MySQL 将数字数据加载到 python/pandas/numpy 数组的最快方法

    我想从 MySQL 表中读取一些数字 双精度 即 float64 数据 数据大小约为 200k 行 MATLAB 参考 tic feature accel off conn database c fetch exec conn select
  • 从 android 发送查询到数据库

    我在 Android 上有一个体育运动列表视图 有没有办法将带有所选选项的 MySQL 查询发送到remote同一张表中包含有关该运动的更多信息的数据库 就像 从桌子上选择足球 提前致谢 扎克 Android 的常见数据库类型是 sqlit
  • 使用从另一个表 MYSQL 获取的值从一个表中选择行

    我的数据库中目前有 2 个 mysql 表 Film and Film Ratings Report Film 的主键是filmid用于识别电影分级Film Ratings Report table 我想知道是否可以仅使用 MYSQL 查询
  • 什么时候数据库被称为嵌入式数据库?

    术语 嵌入式数据库 与 数据库 具有不同的含义吗 我见过的嵌入式数据库有两种定义 嵌入式数据库就像专门为 嵌入式 空间 移动设备等 设计的数据库系统一样 这意味着它们在紧张的环境中 内存 CPU 方面 可以合理地执行 嵌入式数据库就像不需要
  • CakePHP:无法访问 MySQL 数据库

    我是 CakePHP 的新手 刚刚完成配置过程 但很困惑为什么 Cake 无法访问我的 MySQL 数据库 Cake 信息页面显示我的 tmp 目录是可写的 FileEngine 正在用于缓存 不知道这意味着什么 并且我的数据库配置文件存在
  • mysql中的保存点提交回滚[重复]

    这个问题在这里已经有答案了 我们如何在mysql中使用提交 回滚和保存点 CREATE TABLE t test id INT NOT NULL PRIMARY KEY ENGINE InnoDB START TRANSACTION INS
  • 有没有类似Wamp Server的东西? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想知道是否有人知道类似WAMP Server 的程序 包含 PHP MySQL Apache 的多合
  • 在 MySQL 中对连续值进行分组并向这些组添加 id

    我有一个简单的表 我需要确定四行的组 这些组不是连续的 但每行的每一行的值都有 1 例如 language id C 16 C 17 Java 18 Python 19 HTML 65 JavaScript 66 PHP 67 Perl 6
  • 如何使用 mysql 模块在 Nodejs 上列出 mysql 中的列

    我想在nodejs上使用模块mysql列出表中的列 当我运行查询时 SHOW COLUMNS FROM tableName WHERE FIELD columnName 工作正常 我可以知道该列是否存在 但我想列出这些列 并获得一个对象列表
  • 如何确定c3p0 max_statements

    我想知道如何正确确定 c3p0 max statements 使用什么值 我经历过一些缓存死锁 这似乎指向我的 max statements 配置 基于我读过的所有 SO 问答 我正在使用 mysql 当我进行一些有 4 个活动线程的多线程
  • 使用 knex.js 查询多个表

    我想渲染Expres js and knex js两个表仅使用一个 get 函数 以便在一个 HTML 模板中使用两个表中的数据 当我只查询一张表 学校或学生 但我不知道如何处理两张表时 它会起作用 有什么建议吗 app get schoo
  • SQL 条件行插入

    如果满足条件是否可以插入新行 例如 我有这个表 没有主键也没有唯一性 image id tag id 39 8 8 39 5 11 如果 image id 和 tag id 的组合不存在 我想插入一行 例如 INSERT WHERE ima
  • mysql故障转移:如何选择slave作为新的master?

    我是 mysql 新手 当涉及到故障转移时 哪个从机应该晋升为新的主机 例如 A是master B和C是slave A对B和C进行异步复制 在某个时间点 B 从 A 接收的数据多于 C A 崩溃 如果我们将C提升为新的master 并将B的
  • 连接多个表的查询执行速度慢

    我有以下表格 Parts id int idx partnumber varchar idx accountnumber idx enabled Sample data RefUserGroup id int idx value varch
  • 为什么 LOCK TABLES [table] WRITE 不阻止表读取?

    根据http dev mysql com doc refman 5 0 en lock tables html http dev mysql com doc refman 5 0 en lock tables html如果我锁定一张表以在
  • MySQL Match() Against() 区分大小写

    目前 我的数据库是字符集Latin1意义 SELECT FROM TABLE MATCH column1 AGAINST words here IN BOOLEAN MODE 只会返回不敏感的搜索 但问题是我的数据库将通过不敏感和区分大小写

随机推荐

  • 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