join 语句使用

news2025/1/15 22:46:37

目录

前言

创建数据

知识点补充

Join算法Index Nested-Loop

小结:

Join算法Block Nested-Loop

join_buffer放不下驱动表情况

小结:

小表是什么?

总结:

参考内容


前言

在实际开发中,我们一般会有两类问题,为什么我们 DBA 不让使用 join,使用 join 有什么问题呢?如果有两个大小不同的表做 join,应该用哪个表做驱动表呢?MySQL 执行 join 语句的两种可能算法(Index Nested-Loop Join ,Block Nested-Loop Join),这两种算法是由能否使用被驱动表的索引决定的。

创建数据

首先创建表与数据

CREATE TABLE `high`.`testjoin2` 
( `id` INT NOT NULL, 
`index` INT NULL, 
`num` INT NULL, 
PRIMARY KEY ( `id` ), 
INDEX `index` ( `index` ) );

 批量添加数据

PRIMARY KEY ( `id` ), INDEX `index` ( `index` ) );
delimiter ;;
drop procedure idata;
create procedure idata()
begin
  declare i int;
  set i=1;
  while(i<=1000)do
    insert into testjoin2 values(i, i, i);
    set i=i+1;
  end while;
end;;
delimiter ;
call idata();

create table testjoin1 like testjoin2;
insert into testjoin1 (select * from testjoin2 where id<=100)

知识点补充

straight_join :目的是MySQL 使用固定的连接方式执行查询。

这里简单说明一下,join语句如果可以用上被驱动表的索引的算法是Index Nested-Loop Join,反之使用的Block Nested-Loop Join算法。

join_buffer 的大小是由参数 join_buffer_size 设定的,默认值是 256k。

Join算法Index Nested-Loop

这里我们知道了可以用上被驱动表的索引的算法是Index Nested-Loop Join,已知创建的表的index有索引所以sql如下:

EXPLAIN select * from  testjoin1 straight_join testjoin2 on (testjoin1.index=testjoin2.index);

 explain 结果:

 从结果可以看出join的过程中使用了testjoin2的index字段索引。

语句执行流程:

  • 从表 testjoin1中读入一行数据A(扫描 100 行);
  • 从该数据A行中,取出 a 字段到表 testjoin2 里去查找(扫描 100 行);
  • 取出表 testjoin2中满足条件的行,跟数据A组成一行,作为结果集的一部分;
  • 重复执行步骤 1 到 3,直到表 testjoin1的末尾循环结束(总共扫描200行)。

这个过程就跟我们写的嵌套查询类似,并且可以用上被驱动表的索引,所以我们称之为“Index Nested-Loop Join。同时这个过程中驱动表是走全表扫描,而被驱动表是走树搜索。每次在被驱动表查一行数据,要先搜索索引 a,再搜索主键索引。

小结:

使用 join 语句,性能比强行拆成多个单表执行 SQL 语句的性能要好;

如果使用 join 语句的话,需要让小表做驱动表。

Join算法Block Nested-Loop

我们知道用不上被驱动表的索引时了mysql选择的Block Nested-Loop Join算法,所以我们将sql改一下:

EXPLAIN select * from testjoin1 straight_join testjoin2 on (testjoin1.index=testjoin2.num);

 explain 结果:

Extra:Using where; Using join buffer (Block Nested Loop) 可以看出使用的Block Nested Loop算法

sql语句执行流程:

  • 把表 testjoin1的数据读入线程内存 join_buffer 中,因为我们这个语句中写的是 select *,所以是把整个表 testjoin1放入了内存;
  • 扫描表 testjoin2,把表 testjoin2中的每一行取出来,跟 join_buffer 中的数据做对比,满足 join 条件的,作为结果集的一部分返回。

从结果可以看出testjoin1扫描了100行,testjoin2扫描了1000行,因为join_buffer 是以无序数组的方式组织的,因此对表 testjoin2中的每一行,都要做 100 次判断(Block Nested-Loop Join 算法的这 10 万次判断是内存操作),总共需要在内存中做的判断次数是:100*1000=10 万次,(扫描行数=testjoin1.rows*testjoin2.rows)。这时候选择大表还是小表做驱动表,扫描行数、执行耗时是样的。

join_buffer放不下驱动表情况

sql语句执行流程:

  • 把表 testjoin1的数据读入线程内存 join_buffer 中时,放了一部分数据放满了,然后紧接着去扫描testjoin2表 testjoin2中的每一行取出来,跟 join_buffer 中的数据做对比,满足条件的数据放入结果集;
  • 把表 testjoin1的剩下的数据分次放入join_buffer,重复以上操作

所以说testjoin1越小或者是join_buffer越大,分的次数就越小,应该让小表当驱动表

小结:

如果在大表上的 join 操作时,可能回扫描被驱动表很多次,会占用大量的系统资源。所以这种 join 尽量不要用。

使用join时,如果join_buffer_size足够大,无论那个表做驱动表结果都一样;如果join_buffer_size不够大时,应该使用小表当驱动表。

小表是什么?

join语法的两个表按照各自的条件过滤,计算参与 join 的各个字段的总数据量,数据量小的那个表,就是“小表”,应该作为驱动表。

总结:

如果可以使用被驱动表的索引可以使用join 语句;

如果不能使用被驱动表的索引,然后使用 Block Nested-Loop Join 算法,尽量不要使用join;

在使用 join 的时候,应该让小表做驱动表。

参考内容

如果想知道更多详细内容请自行学习《极客时间mysql实战45讲》34 | 到底可不可以使用join?-极客时间

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/501448.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

腾讯云2核4G服务器5M带宽轻量CPU性能、流量和系统盘测试

腾讯云轻量应用服务器2核4G5M配置&#xff0c;自带5M公网带宽&#xff0c;5M带宽下载速度峰值可达640KB/秒&#xff0c;系统盘为60GB SSD盘&#xff0c;每月500GB流量包&#xff0c;折合每天16GB流量。腾讯云百科来详细说下腾讯云轻量应用服务器2核4G5M配置、CPU型号处理器主频…

威联通nas服务器中勒索病毒被encrypted勒索病毒攻击怎么办有哪些预防措施

威联通是一家专业提供网络存储设备和应用方案的公司&#xff0c;旗下NAS服务器因为实用、多功能而深受用户喜欢&#xff0c;但是NAS服务器在使用过程中也面临许多安全问题&#xff0c;例如被encrypted勒索病毒攻击。下面将为大家介绍encrypted勒索病毒在威联通NAS服务器上的危害…

黑马---Redis入门到实战【实战篇】

一、短信登录 基于session实现短信登录的流程 实现发送短信验证码功能 发送验证码功能&#xff1a; Overridepublic Result sendCode(String phone, HttpSession session) {//1.校验手机号if(RegexUtils.isPhoneInvalid(phone)){//2.如果不符合&#xff0c;返回错误信息return…

Java 基础进阶篇(十三)—— 异常处理机制

文章目录 一、异常概述、体系二、异常的分类三、异常的默认处理流程四、异常的处理机制4.1 编译时异常的处理机制4.1.1 方式一&#xff1a;抛出异常4.1.2 方式二&#xff1a;捕获异常4.1.3 方式三&#xff1a;前两者结合 4.2 运行时异常的处理机制 五、自定义异常5.1 自定义编译…

程序员面试金典10.*

文章目录 10.1合并排序的数组10.02变位词组10.03搜索旋转数组10.05稀疏数组搜索10.09排序矩阵查找10.10 数字流的秩10.11 峰与谷 10.1合并排序的数组 这个就从后往前加入到新数组里就行。如果B的下标是-1则结束&#xff0c;A的下标是-1则一直加B的元素。 class Solution { pub…

挑战14天学完Python---初识python基本图形绘制

往期文章 目录 往期文章前言1."Python蟒蛇绘制"实例2.Python标准库 之turtle库3. 面向对象编程风格3.1 import更多玩法3.1.1使用from和import保留字共同完成3.1.2 使用import和as保留字共同完成 4.turtle的原(wan)理 (fa)4.1 turtle绘图窗体布局---turtul.setup()4.2…

京东小程序折叠屏适配探索 | 京东云技术团队

前言 随着近年来手机行业的飞速发展&#xff0c;手机从功能机进入到智能机&#xff0c;手机屏幕占比也随着技术和系统的进步越来越大&#xff0c;特别是Android 10推出以后&#xff0c;折叠屏逐渐成为Android手机发展的趋势。 图 1 Android手机屏幕发展趋势 京东小程序近年来…

Python程序员辞职后,如何踏出自由职业的第一步,聊聊我自己的看法

大家好&#xff0c;我是兴哥。有个广州的朋友说他辞职了&#xff0c;想要自由职业该怎么开始第一步呢&#xff1f;我问他你之前的收入月薪是多少&#xff0c;他说2万出头。我不得不说&#xff0c;对于写项目的自由职业程序员&#xff0c;2万是一个极高的门槛。但既然他已经辞职…

第三十章 React的路由基本使用

关于React路由&#xff0c;我们在学习之前先了解一下其他知识点&#xff1a;SPA应用、路由的理解、react中如何使用路由。 SPA应用的理解 我们知道React脚手架给我们构建的是一个单页应用程序&#xff08;SPA&#xff09;&#xff0c;在页面加载时&#xff0c;只会加载一个HT…

2.Redis入门概述

1.Redis是什么 Remote Dictionary Server(远程字典服务)是完全开源的&#xff0c;使用ANSIC语言编写遵守BSD协议&#xff0c; 是一个高性能的Key-Value数据库&#xff0c; 提供了丰富的数据结构&#xff0c;例如String、Hash、List、Set、SortedSet等等。 数据是存在内存中的&a…

学会这几个Word技巧,让你办公省时又省力(二)

Word是我们经常用到的办公软件&#xff0c;下面分享的几个小技巧&#xff0c;可以提高你的办公效率&#xff0c;一起看看吧。 1. 改变Word文档的背景颜色 有时候我们打开的Word文档是有颜色的&#xff0c;如果你想恢复白色背景&#xff0c;或者改成其他颜色&#xff0c;只…

《Linux 内核设计与实现》08. 下半部和推后执行的工作

文章目录 下半部软中断软中断的实现使用软中断 tasklettasklet 的实现使用 tasklet 工作队列工作队列的实现使用工作队列 下半部 中断处理程序的局限性&#xff1a; 中断处理程序以异步方式执行&#xff0c;并且可能打断其它代码&#xff0c;因此为了避免被打断的代码停止时间…

PR控制以及使用PR控制用于单相离/并网逆变器

文章目录 前言基本知识实际使用单相离网逆变器单相并网逆变器 PR控制器离散化基本知识 DSP实现总结 前言 最近想学习一下并网逆变器&#xff0c;需要用到PR控制&#xff0c;全网找遍了许多学习资料&#xff0c;终于掌握的差不多了&#xff0c;在此做个记录&#xff0c;以及个人…

【每日一题】23年4月

文章目录 C 技术点多边三角形剖分的最低得分&#xff08;dp思路&#xff0c;选不选问题&#xff09;移动石子到连续&#xff08;思路&#xff09;1027. 最长等差数列(动态规划)1105. 填充书架&#xff08;动态规划&#xff09;1031 两个非重叠子数组的最大和1163.按字典序排在最…

【Java 】从源码全面解析Java 线程池

文章目录 一、引言二、使用三、源码1、初始化1.1 拒绝策略1.1.1 AbortPolicy1.1.2 CallerRunsPolicy1.1.3 DiscardOldestPolicy1.1.4 DiscardPolicy1.1.5 自定义拒绝策略1.2 其余变量 2、线程池的execute方法3、线程池的addWorker方法3.1 校验3.2 添加线程 4、线程池的 worker …

PostgreSQL 基础知识:psql 提示和技巧

对于积极使用和连接到 PostgreSQL 数据库的任何开发人员或 DBA 来说&#xff0c;能够访问psql命令行工具是必不可少的。在我们的第一篇文章中&#xff0c;我们讨论了 psql的简要历史&#xff0c;并演示了如何在您选择的平台上安装它并连接到 PostgreSQL 数据库。 在本文中&…

使用腾讯云快速完成网站备案的详细过程

最近总是被备案弄得血压飙升&#xff0c;明明是一件很简单的事情&#xff0c;不知道大家为什么搞得那么复杂&#xff0c;首先了解下为什么要备案&#xff0c;根据国务院令第292号《互联网信息服务管理办法》和 《非经营性互联网信息服务备案管理办法》规定&#xff0c;国家对经…

【TCP四次挥手】

文章目录 TCP 四次挥手过程是怎样的&#xff1f;为什么挥手需要四次&#xff1f;第一次挥手丢失了&#xff0c;会发生什么&#xff1f;第二次挥手丢失了&#xff0c;会发生什么&#xff1f;第三次挥手丢失了&#xff0c;会发生什么&#xff1f;第四次挥手丢失了&#xff0c;会发…

Lecture 13(Extra Material):Q-Learning

目录 Introduction of Q-Learning Tips of Q-Learning Double DQN Dueling DQN Prioritized Reply Multi-step Noisy Net Distributional Q-function Rainbow Q-Learning for Continuous Actions Introduction of Q-Learning Critic: The output values of a critic…

为生信写的Python简明教程 | 视频3

开源生信 Python教程 生信专用简明 Python 文字和视频教程 源码在&#xff1a;https://github.com/Tong-Chen/Bioinfo_course_python 目录 背景介绍 编程开篇为什么学习Python如何安装Python如何运行Python命令和脚本使用什么编辑器写Python脚本Python程序事例Python基本语法 数…