关系型数据库还有一个重要的概念:Join(连接)。使用Join有好处,也会坏处,只有我们明白了其中的原理,才能更多的使用Join。切记不可以:
业务之上,再复杂的查询也在一个连表语句中完成。
【资料图】
敬而远之,DBA每次上报的慢查询都是连接查询导致的,我再也不用了。
连接简介连接的本质我们先来创建两个简单的表,再初始化一些数据
CREATE TABLE t1 (m1 int, n1 varchar(1));CREATE TABLE t2 (m2 int, n2 varchar(1));INSERT INTO t1 VALUES(1, "a"), (2 , "b") ,(3 ,"c") ; INSERT INTO t2 VALUES(2 , "b"), (3 , "c "),(4 , "d");
从本质上来说,连接就是把各个表的数据都取出来进行匹配,t1 和 t2 的两个表连接起来就是这样的:
连接语法:
select * from t1, t2;
如果乐意,我们可以连接任意数量的表。但是如果不加任何限制条件的话,这个数据量是非常大的,我们现实中使用都是会加上限制条件的。我们来看下下面这条语句
select * from t1,t2 where t1.m1 > 1 and t1.m1 = t2.m2 and t2.n2 = "c";
这个连接查询的执行过程大致如下
首先确定第一个需要查询 表称为驱动表(t1)
步骤1中从驱动表 (t1) 中每获得一条记录,都要去被驱动表 (t2) 中查询匹配。
从上面的步骤,可以看出上述的连表查询我们需要查询一次t1,两次t2。也就是说,两表的连接查询中,需要查询一次驱动表,被驱动表需要查询多次。
这里需要注意下,并不是将所有满足条件的驱动表记录先查询出来放到一个地方,然后再去被驱动表中查询,(如果满足条件的驱动表中的数据非常多,那要需要多大的内存呀。) 所以是每获得一条驱动表记录就去被驱动表中查询。
内连接和外连接我们再来创建两个表,并插入一些数据
CREATE TABLE student ( number INT NOT NULL Auto_increment comment"学号",name varchar (5) COMMENT "姓名",major varchar (30) comment "专业",PRIMARY KEY (number));CREATE TABLE score ( number INT comment"学号",subject varchar (30) COMMENT "科目",score TINYINT comment "成绩",PRIMARY KEY (number, subject));INSERT INTO `student` (`number`, `name`, `major`) VALUES ("20230301", "小赵", "计算机科学");INSERT INTO `student` (`number`, `name`, `major`) VALUES ("20230302", "小钱", "通信");INSERT INTO `student` (`number`, `name`, `major`) VALUES ("20230303", "小孙", "土木工程");INSERT INTO `score` (`number`, `subject`, `score`) VALUES ("20230301", "高等数学", "60");INSERT INTO `score` (`number`, `subject`, `score`) VALUES ("20230301", "英语", "70");INSERT INTO `score` (`number`, `subject`, `score`) VALUES ("20230302", "高等数学", "80");INSERT INTO `score` (`number`, `subject`, `score`) VALUES ("20230302", "英语", "90");
如果我们想把所有的学生的成绩都查出来,只需要这样执行:
select s1.number, s1.name, s1.major, s2.subject, s2.score from student as s1 , score as s2 where s1.number = s2.number;
有个问题就是小孙因为某些原因没有参加考试,所以在结果表中没有对应 的成绩记录。如果老师想查看所有学生的考试成绩,即使是缺考的学生 他们的成绩也应该展示出来。
为了解决这个问题,就有了内连接和外连接的概念:
对于内连接的两个表,若驱动表中的记录在被驱动表找不到匹配的记录,则该记录不会加入到最后的结果集。前面提到的连接都是内连接。对于外连接的两个表,时驱动表中的记录在被驱动表中没有匹配的记录,也仍然需要加入到结果集。MySQL 中,根据选取的驱动表的不同,外连接可以细分为
左外连接 选取左侧的表为驱动表。右外连接·选取右侧的表为驱动表。当我们使用外连接的时候 有时候我们也不想把驱动表的全部记录都加入到最后的结果集中,这个时候我们就要使用过滤条件了。
• WHERE 子句中的过滤条件:不论是内连接还是外连接 凡是不符合 WHERE 子句中过滤条件的记录都不会被加入到最后的结果集。
• ON 子句中的过滤条件:对于外连接的驱动表中的记录来说,如果无法在被驱动表中找到匹配 ON 子句 中过滤条件的记录 那么该驱动表记录仍然会被加入到结果集中,对应的被驱动表记录的各个字段使用NULL 值填充。
所以上述的需求我们可以左查询这样来做:
select s1.number, s1.name, s1.major, s2.subject, s2.score from student as s1 left join score as s2 on s1.number = s2.number;
语法:
#左连接select * from t1 left join t2 on "连接条件" where "普通过滤条件"#右连接select * from t1 right join t2 on "连接条件" where "普通过滤条件"
内连接的另一种写法,也是常用写法
select s1.number, s1.name, s1.major, s2.subject, s2.score from student as s1 inner join score as s2 where s1.number = s2.number;
语法:
select * from t1 inner join t2 on "连接条件" where "过滤条件"连接原理
上述说了这么多,知识简单回顾一下连接,左连接,右连接这些概念。接下来我们重点说一下 MySQL 采用了什么样的算法来进行表与表之前的连接。
Nested-Loop Join (嵌套循环连接) NLJ前面我们已经介绍过了执行连接查询的大致步骤了,我们再来简单回顾一下
步骤1:选取驱动表,使用相关的过滤条件,选取代价最低的单表访问方法来执行访问。步骤2:对步骤1中查询到的驱动表结果中的每一条记录,都分别在被驱动表中匹配符合条件的记录。如果有三个表,那么步骤2中得到的结果集就像是新的驱动表,然后第三个表就成为了驱动表,重复上述的过程。整个过程就像是一个嵌套循环,所以这种连接方式称为 嵌套循环连接 ,这是最简单也是最笨的一种连接查询算法。大致处理过程如下:
for each row in t1 matching range { for each row in t2 matching reference key { for each row in t3 { if row satisfies join conditions, send to client } }}
需要注意的是对于获套循环连接算法法来说,每当我们从驱动表中得到了一条记录时,就根据这条记录立时到被驱动表中查询一次,如果得到了匹配的记录,就把组合后 的记录发送给客户端,然后再到驱动表中获取下一条记录。这个过程将重复进行。
有什么方式可以优化吗使用索引加快连接速度这个是我们比较熟悉的方式,也是相对来说最有用的方式,在被驱动表上创建合适的索引,只返回必要的字段等都可以起到一些优化的作用。
Block Nested-Loop Join(块嵌套循环连接)BNL每次访问被驱动表,其表中的记录都会被加载到内存中,然后再从驱动表中取出一条与其匹配,匹配结束后清楚内存,然后再从驱动表中加载一条记录,然后把被驱动表的记录加载到内存匹配,如果这个被驱动表中的数据特别多而且不能使用索引进行访问,那就相当于要从磁盘上读这个表好多次,这个IO的代价就非常大了。所以我们得想办法,尽量减少被驱动表的访问次数,于是就出现了下面这种方式。
不再是逐条获取驱动表的数据,而是一块一块的获取,引入join buffer 缓冲区,将驱动表join 相关的部分数据列(大小受join buffer的限制)缓存到 join buffer中,然后开始扫描被驱动表,被驱动表的每一条记录一次性和join buffer中所有的驱动表记录进行匹配(内存中操作)。将简单嵌套循环中的多次比较合并成一次,降低了备驱动表的访问频率。
这里缓存的不只是关联表的列,select后面的列也会缓存起来。所以查询的时候尽量减少不必要的字段,可以让join buffer中可以存放更多的列。
join_buffer_size的最大值在32为系统中可以申请4G,在64为操作系统中可以申请大于4G的空间。
MySQL对于被驱动表的关联字段没索引的关联查询,一般都会使用 BNL 算法。如果有索引一般选择 NLJ 算法,有 索引的情况下 NLJ 算法比 BNL算法性能更高。
关联查询优化总结超过三个表禁止 join。【阿里巴巴JAVA开发手册】需要 join 的字段,数据类型必须绝对一致;【阿里巴巴JAVA开发手册】多表关联查询时,保证被关联的字段需要有索引,尽量选择NLJ算法。【阿里巴巴JAVA开发手册】小表驱动大表,写多表连接sql时如果明确知道哪张表是小表可以用straight_join写法固定连接驱动方式,省去mysql优化器自己判断的时间-
资讯:MySQL两个表的亲密接触-连接查询的原理关系型数据库还有一个重要的概念:Join(连接)。使用Join有好处,也会坏处,只有我们明白了其中的原理,才能更多的使用Join。切记不可以:业
-
创新难扳三年连亏 全聚德白折腾了?创新难扳三年连亏全聚德白折腾了?,闭店,经营,全聚德,餐饮业,老字号
-
信贷增量首次突破10万亿 机构看好二季度市场走势4月11日,我国首季相关统计数据相继出炉。央行当日发布的数据显示,当季新增人民币贷款同比创新高,信贷增量为有记录以来首次突破10万亿元。其
-
送父母的礼物送父母最喜欢的东西,如果是年纪大的人,就可以送父母一些比较实用的东西,年纪大的人都需要的东西,像是保健品,像现在天气冷了
-
世界观焦点:纪录片与“书”有约【影视锐评】作者:张延利(中国纪录片网负责人)四月是书香弥漫的时节,4月2日是国际儿童图书日,4月23日是世界读书日,所
-
五大联赛争冠形势:阿森纳领先曼城6分 巴萨多皇马13分 德甲最激烈-焦点日报北京时间4月11日,欧洲五大联赛结束新一轮的较量,争冠形势又有了新的变化,我们不妨来盘点一番。英超:阿森纳领先曼城6分第29轮,曼城凭借哈
-
大号两双!崔永熙砍下17分15篮板 正负值+7CBA季后赛,广州89-80击败山东,总比分2-0晋级。本场比赛,广州球员崔永熙表现不错,出场43分钟16投6中,三分6中2、罚球6中3砍下17分15个篮板
-
10.6万亿元!一季度我国新增人民币贷款同比创新高_全球视讯我国首季金融统计数据11日出炉,当季新增人民币贷款同比创新高。
-
阿拉巴:希望安切洛蒂明年继续执教 曼城VS拜仁我支持后者-天天新动态阿拉巴:“我是一名灵活的球员,我感觉最好的地方是中后卫,但我想给球队带来帮助,无论踢任何位置。”阿拉巴:“我们必须从第一分钟就全力...
-
世界热资讯!一季度我国人民币贷款增加10.6万亿元 同比多增2.27万亿元月末人民币贷款余额225 45万亿元,同比增长11 8%,增速分别比上月末和上年同期高0 2个和0 3个百分点。月末人民币存款余额273 91万亿元,同比增
-
消防安全无小事 隐患排查保平安 鹤壁示范区淇水湾街道扎实开展高层建筑消防安全整治-今日视点为切实加强高层建筑消防安全管理,消除安全隐患,有效防范和坚决遏制高层建筑火灾事故发生,保障广大人民群众的生命和财产安全。连日来,鹤壁
-
镜花水月的意思_镜花水月简谱1、3565321235231d6321232123356532123567621235321166
-
通过瞳孔识别用户状态 苹果新专利公布凤凰网科技讯4月11日消息据天眼查App显示,苹果公司申请的“利用亮度变化来确定用户特征”专利公布。摘要显示,该专利是基于用户对一部分或...
-
魔方速拧公式OLL_魔方速拧公式 天天快消息1、既然是速度扭转课程,这里假设学习者可以独立完成魔方。所以这里只介绍快扭这种高级玩法。2、这里需要强调的是,在快捻的过
-
每日简讯:开封市龙亭区举办珍稀食用菌产业发展实地考察活动近日,开封市龙亭区农业农村局副局长、乡村振兴局局长耿晓迎、柳园口乡副乡长樊腾飞等带领各社区书记及种植大户代表调研辖区珍稀
-
沙尘暴能被“消灭”吗?频繁来袭谁是元凶?沙尘暴蓝色预警持续发布,不少网友发出疑问:为何植树造林没能挡住一轮轮的风沙,地球上的沙尘能被“消灭”吗?来听气象专家的科普解读。
-
也门政府欢迎沙特同胡塞武装举行和谈 焦点热门据新华社援引亚丁消息:也门政府10日发表声明,欢迎沙特阿拉伯代表团同胡塞武装举行和谈。 声明说,也门政府对沙特同胡塞武装的外交努力表
-
华润置地80亿元消费基础设ABS债券项目更新至“已反馈” 天天微动态观点网讯:4月11日,根据深交所信息显示,中信证券-华润置地消费基础设施资产支持专项计划1-3期,项目更新为“已反馈”。观点新媒体获悉,...
-
厦门羽毛球队首次以公开比赛的方式选拔人才 焦点简讯厦门羽毛球队首次以公开比赛的方式选拔人才!获得每项比赛前两名的选手,都可以在今年暑假进入厦门队集训。近日,由厦门市羽毛球
-
世界快看:店铺年审不合格,需要添加微信办理?当心可能是诈骗每日甘肃网4月11日讯据兰州晚报报道4月10日,市民孙女士向本报“记者跑腿”栏目反映:她在西站开了一家小饰品店,几天前,有人给她打电话说...
-
今日新股提醒:2只申购 3只公布中签号 当前信息今日新股提醒:2只申购3只公布中签号,【新股提醒】申购:中船特气、晶升股份上市:无中签号:北方长龙、颀中科技、高华科技中签率:无缴款:北
-
总胆红素和直接胆红素高说明什么_总胆红素和间接胆红素高说明什么1、如果总胆红素和间接胆红素都升高了,就要进一步确定直接胆红素是否升高了。如果直接胆红素和间接胆红素均升高,往往提示有肝
-
卷不动的光伏中下游,隆基下一步要去哪?丨见智研究 世界热点评光伏硅料即使降价依然赚了产业大头,而中下游却只能拼命赚个辛苦钱。光伏中下游的卷已经充分体现在了财报里。隆基公布业绩快报2
-
焦点热议:百度快速收录技术(百度快速收录)1、首先进入百度搜索资源平台(百度站长),直接用百度账号登录即可。如果不知道网址,可以去百度一下。2、单击用户中心-站点
-
【热闻】晨化股份(300610.SZ)发预减,预计一季度净利润1446万元至1859万元,同比下降55%至65%智通财经APP讯晨化股份300610300610SZ披露2023年第一季度业绩预告公司预计归属于上市公司股东的净利润1446万元–1859万元同比下降5565扣除非经
-
“移动”窗口暖民心 咸安民警“上门办”解民忧 天天快资讯近日,咸安公安分局马桥派出所主动作为,为困难群众上门服务,全力为群众解难题,用心考虑群众需求,赢得了辖区企业和群众的一致好评。
-
【当前热闻】街道、社区、物业“三级联动”东湖街道深化垃圾分类基层治理读特客户端·深圳新闻网2023年3月13日讯(记者李慧通讯员陈燕霞)为全面贯彻落实《深圳市推进生活垃圾分类工作“铁十条”》,进一步发挥基...
-
世界快讯:倡劳动之美 促全面发展——岑巩县思旸镇第一小学开展劳动教育实践活动为进一步落实德智体美劳全面发展的育人理念和“双减”工作有关要求,让学生在日常学习生活中牢固树立劳动最光荣、劳动最崇高、劳
-
环球最资讯丨金隅股份拟发行20亿元超短期融资券 期限247天本期债券发行金额为人民币20亿元,用于偿还发行人有息负债。发行期限247天。
-
全球快资讯:甄英莲的故事_甄英莲1、朋友。2、甄英莲就是香菱。3、在薛蟠远游时,香菱住进了大观园薛宝钗的住所,开始学诗,并得到了众姐妹和宝玉的帮助。4、