MySQLjoin实现原理
join实现原理
MySQl在设计时,采用了这样的思路:针对主要应用场景选择一个或几个性能优异的核心算法作为引擎,然后努力将一些非主要应用场景作为该算法的特例或变种植入到引擎当中。(systemconstrefrefeqrangeindexall)join实现原理
Join是select的核心,Join是根。Joinbuffer:BlockNestedLoopJoin(BNL)joinbuffer只有当join查询中有表用到以下查询:All:全表扫描,Index:全索引扫描,Range:范围扫描,如in(),id18000,indexmerge:的时候,join查询才会用到joinbuffer。在MySQL中只有一种Join算法:NestedLoopJoin(没有其他很多数据库所提供的HashJoin,也没有SortMergeJoin)。
驱动表用这个表作为第一个查询的表,其他表在这个基础上递归。
NestedLoopJoinNestedLoopJoin就是通过驱动表的结果集作为循环基础数据,然后一条一条的通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果。如果还有第三个参与Join,则再通过前两个表的Join结果集作为循环基础数据,再一次通过循环查询条件到第三个表中查询数据,如此往复。接下来通过一个三表join查询来说明mysql的NestedLoopJoin的实现方式。selectm。subjectmsgsubject,c。contentmsgcontentfromusergroupg,groupmessagem,groupmessagecontentcwhereg。userid1andm。groupidg。groupidandc。groupmsgidm。id;使用explain看看执行计划:Explainselectm。subjectmsgsubject,c。contentmsgcontentfromusergroupg,groupmessagem,groupmessagecontentcwhereg。userid1andm。groupidg。groupidandc。groupmsgidm。id;结果如下:1。rowid:1selecttype:SIMPLEtable:gtype:refpossiblekeys:usergroupgidind,usergroupuidind,usergroupgiduidindkey:usergroupuidindkeylen:4ref:constrows:2Extra:2。rowid:1selecttype:SIMPLEtable:mtype:refpossiblekeys:PRIMARY,idxgroupmessagegiduidkey:idxgroupmessagegiduidkeylen:4ref:g。groupid(根据g表的groupid查,所以要先查出g表记录,每条g表符合记录对m表递归)rows:3Extra:3。rowid:1selecttype:SIMPLEtable:ctype:refpossiblekeys:idxgroupmessagecontentmsgidkey:idxgroupmessagecontentmsgidkeylen:4ref:m。id(根据m表的id查,所以要先查出m表记录,每条m表符合条件记录递归c表)rows:2Extra:从结果可以看出,explain选择usergroup作为驱动表,首先通过索引usergroupuidind来进行const条件的索引ref查找,然后用usergroup表中过滤出来的结果集groupid字段作为查询条件,对groupmessage循环查询,然后再用过滤出来的结果集中的groupmessage的id作为条件与groupmessagecontent的groupmsgid进行循环比较查询,获得最终的结果。这个过程可以通过如下伪代码来表示:foreachrecordgrecintableusergroupthatgrec。userid1{foreachrecordmrecingroupmessagethatmrec。groupidgrec。groupid{foreachrecordcrecingroupmessagecontentthatcrec。groupmsgidmrec。idpassthe(grec。userid,mrec。subject,crec。content)rowcombinationtooutput;}}如果去掉groupmessagecontent表上面的groupmsgid字段的索引,执行计划会有所不一样。dropindexidxgroupmessagecontentmsgidongroupmessagecontent;Explainselectm。subjectmsgsubject,c。contentmsgcontentfromusergroupg,groupmessagem,groupmessagecontentcwhereg。userid1andm。groupidg。groupidandc。groupmsgidm。id;得到的执行计划如下:1。rowid:1selecttype:SIMPLEtable:gtype:refpossiblekeys:usergroupuidindkey:usergroupuidindkeylen:4ref:constrows:2Extra:2。rowid:1selecttype:SIMPLEtable:mtype:refpossiblekeys:PRIMARY,idxgroupmessagegiduidkey:idxgroupmessagegiduidkeylen:4ref:g。groupidrows:3Extra:3。rowid:1selecttype:SIMPLEtable:ctype:ALLpossiblekeys:NULLkey:NULLkeylen:NULLref:NULLrows:96Extra:Usingwhere;Usingjoinbuffer因为删除了索引,所以groupmessagecontent的访问从ref变成了ALL,keys相关的信息也变成了NULL,Extra信息也变成了UsingWhere和Usingjoinbuffer,这时获取content内容只能通过对全表的数据进行where过滤才能获取。Usingjoinbuffer是指使用到了Cache,只有当join类型为ALL,index,range或者是indexmerge的时候才会使用joinbuffer,它的使用过程可以用下面代码来表示:foreachrecordgrecintableusergroup{foreachrecordmrecingroupmessagethatmrec。groupidgrec。groupid{put(grec,mrec)intothejoinbufferif(bufferisfull)flushbuffer();}}flushbuffer(){foreachrecordcrecingroupmessagecontentthatcrec。groupmsgidcrec。id{foreachrecordinthejoinbufferpass(grec。userid,mrec。subject,crec。content)rowcombinationtooutput;}emptythebuffer;}在实现过程中可以看到把usergroup和groupmessage的结果集放到joinbuffer中,而不用每次usergroup和groupmessage关联后马上和groupmessagecontent关联,这也是没有必要的;需要注意的是joinbuffer中只保留查询结果中出现的列值,它的大小不依赖于表的大小,我们在伪代码中看到当joinbuffer被填满后,mysql将会flushbuffer,flushbuffer时将3者做关联并返回到输出output。
针对join实现原理想到的join语句的优化1、在query中用orderby时,尽可能利用已有的索引避免实际的排序计算;2、在有些query的优化过程中,为了避免实际的排序操作而调整索引字段的顺序,甚至是增加索引字段也是值得的。当然,在调整索引前,同时还需要评估调整该索引对其他query所带来的影响,平衡整体得失。3、用小结果集驱动大结果集,尽量减少join语句中的NestedLoop的循环总次数;4、优先优化NestedLoop的内层循环,因为内层循环是循环中执行次数最多的,每次循环提升很小的性能都能在整个循环中提升很大的性能;5、对被驱动表的join字段上建立索引(前面看到,没有索引的要做全表扫描);6、当被驱动表的join字段上无法建立索引的时候,设置足够的JoinBufferSize,当mysql对条件字段进行排序时,如果需要排序字段的总长度大于该参数的值的时候,mysql就会对需要排序的字段使用临时表进行分段,这样也会有性能的消耗。
美媒美指控俄黑客网络攻击全球能源设施据美国《华尔街日报》网站3月24日报道,美国司法部周四启动了对4名俄罗斯公民的指控,理由是他们多年来一直在针对美国和全世界数以千计的计算机实施黑客攻击活动,目的是进入电脑系统从……
创新,让科学轻量化呈现来源:人民网人民日报二氧化碳怎么变成淀粉?黑土地为何被称为耕地中的大熊猫?一元二次方程与规范场论究竟有何联系这些有趣的问题都是中国科学院2022跨年科学演讲的内容,吸引了……
展现华为科技之美,全新华为P50E手机正式开售科技不断在变化,智能手机成为了人们生活中不可分割的一部分。我们在追求手机性能的同时,也会对手机的颜值与功能有着较高要求。华为P50E手机能够满足我们对手机科技与美学的全部需求,……
支付宝里的钱长期不用会被清零吗?支付宝里面的资金长期不用,肯定不会清零。余额宝里面的资金随时可以支取对于支付宝里面的余额宝、余利宝等货币基金产品来说,你将资金放在其中进行理财,随时都可以支取或者直接用于……
印度将成全球第二大5G市场,华为成功收入囊中,有何重要意义?5G商用进程正被一再提速,各国的5G之争也进入焦灼阶段。由于华为等企业在5G技术上取得的超群成绩,中国5G龙头的优势似乎已经不言而喻;韩国、美国和欧洲国家等也正争分夺秒,希望能……
现在滴滴顺风车是如何规定的,还属于非法营运吗?老百姓需要顺风车,顺风车符合民意,不要因为一两件事就全盘否定顺风车,这是极不公平的。现在的出租车可以说更不规范,请问以前全国出租车出事的还少吗?只是出租车出了事大家认为习以为常……
iPhone11pro和iPhone12mini怎么选?一、参数对比二、性能测评手机屏幕iphone12mini:采用了一块5。4英寸的OLED屏幕支持23401080像素分辨率,ppi达到了476iphon……
长测报告红米K40使用45天,真实详尽的使用报告红米k40作为红米的当家旗舰已经发布,凭借超高的性价比瞬间点燃市场,抢购的是必须的,红米K40上市之后很多人进行了测评或者开箱,但是我个人看一款手机是否好用仅靠几分钟的开箱或者……
赴美上市,赚钱还是送钱?大家有个误区啊,赴美上市就是不爱国的表现狭隘了。不是滴滴,前两天不是从美股准备退市吗?很多人的关注点不在于他犯了什么错,而是在你为什么去美股上市,……
有点恐怖,怎样才可以防止自己被人肉搜索呢?怎么防止自己被人肉搜索?那么我就谈谈一般都有哪些人肉搜索手段吧,以此提醒大家如何防止被人肉搜索。用一张照片查出你的详细地址现在的智能手机相机设置里一般都会有这一项设置保存……
十四部门引导外卖等互联网企业下调餐饮业商户服务费标准2月18日,国家发改委等14部门印发《关于促进服务业领域困难行业恢复发展的若干政策》。在餐饮业纾困扶持措施中,提出要引导外卖等互联网平台企业进一步下调餐饮业商户服务费标准……
远程办公新模式,企业不妨试一试新华社北京2月17日电2月17日,《新华每日电讯》发表题为《远程办公新模式,企业不妨试一试》的评论。不用天天挤早高峰地铁,不用每天为打卡的最后一秒焦虑,可以自己选择办公地……