热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关系型数据库的物理连接

在开发中常听到的leftjoin,InnerJOIN,rightjoin,crossjoin这些连接都是数据库的逻辑连接,那么数据库在执行这些连接的时候,数据库是如何在底层实现表的关联

在开发中常听到的 left join,Inner JOIN ,right join ,cross join 这些连接都是数据库的逻辑连接,那么数据库在执行这些连接的时候,数据库是如何在底层实现表的关联的呢?这就是物理连接
目前大部分关系型数据库支持3种物理连接(mysql 貌似到5.6未知仅支持嵌套连接)
数据库的物理连接:
数据库接两个表时候,会考虑3种方法:嵌套连接,合并连接,散列连接。3种方法的连接都有一个表被选为外表(只扫描一次),一个表被选为内表(坑内扫描多次)。如果查询连接了多个表,每次查询只能连接2各表,并保存把中间结果,用户连接另外的表。
1、嵌套连接:外表只扫描一次,而针对外表的每一行都需要扫描一次內表。(注意:连接不能用long或lob字段)
2、合并连接:合并连接需要一个等式连接词(A.col1=B.col1),还要求根据连接列对两个连接的表进行排序。合并连接內表和外表都只扫描一次,有时情况下需要再次扫描內表的部分值,例如,外表存在重复值的情况下。所以优化器通常选择重复值较少的表作为外表。
3、散列连接:散列连接需要一个或多个等式连接谓词,其中每个谓词的类型相同。char类型长度必须相同。decimal进度必须相同。散列连接可以处理多个等式谓词。对于散列连接,首先扫描內表(也称为构件表 build table),表中的行被复制到内存缓冲区。根据“散列键(hash key)”,这些缓冲区被分为几个分区,如果内存中没有足够的空间容纳整个表,则有些分区被写入磁盘上的临时表。然后扫描外表。然后扫描外表(探测表)。对于外表中的每一行,对连接列应用同意散列算法。如果所获得的散列键与行的散列键相匹配,读取分区里面的所有行并应用连接谓词。如果与探测表行匹配的分区在内存中,则读取分区并应用连接谓词将立即进行。如果分区被写入临时表,则探测行也别写入临时表。最后,匹配统一分区行和对应分区被一起处理。


优化器使用3种连接的场景:
嵌套连接:
对于被连接的数据子集较小的情况,nested loop连接是个较好的选择。nested loop就是扫描一个表,每读到一条记录,就根据索引去另一个表里面查找,没有索引一般就不会是 nested loops。
一般在nested loop中, 驱动表满足条件结果集不大,被驱动表的连接字段要有索引,这样就走nstedloop。如果驱动表返回记录太多,就不适合nested loops了。如果连接字段没有索引,则适合走hash join,因为不需要索引。
Inner table被Outer table驱动,outer table返回的每一行都要在inner table中检索到与之匹配的行。
Outer table: 小表、驱动表
Inner table: 被驱动表、大表

哈希连接: 哈希连接是做大数据集连接时的常用方式。优化器扫描小表(或数据源),利用连接键(也就是根据连接字段计算hash值)在内存中建立hash表,然后扫描大表,每读到一条记录就来探测hash表一次,找出与hash表匹配的行。
当小表可以全部放入内存中,其成本接近全表扫描两个表的成本之和。如果表很大不能完全放入内存,这时优化器会将它分割成若干不同的分区,不能放入内存的部分就把该分区写入磁盘的临时段,此时要有较大的临时段从而尽量提高I/O 的性能。临时段中的分区都需要换进内存做hash join。这时候成本接近于全表扫描小表+分区数*全表扫描大表的代价和。
至于两个表都进行分区,其好处是可以使用parallel query,就是多个进程同时对不同的分区进行join,然后再合并。但是复杂。
以下条件下hash join可能有优势:
两个巨大的表之间的连接。
在一个巨大的表和一个小表之间的连接。

合并连接:
对连接的每个表做table access full;
对table access full的结果按照连接键进行排序;
进行merge join对排序结果进行合并。
Sort merge join性能开销几乎都在前两步。相较于前两种连接,合并连接的速度最快的。但也看数据库的索引和数据量情况。

通常情况下河西连接的效果都比合并连接要好,然而如果行源已经被排过序,在执行合并连接时不需要再排序了,这时合并连接的性能会优于哈希连接。
在全表扫描比索引范围扫描再通过rowid进行表访问更可取的情况下,合并会比嵌套性能更佳。

各类关系型数据库都有相应参数可以强制指定那一种连接进行测试。。。


推荐阅读
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • PHP设置MySQL字符集的方法及使用mysqli_set_charset函数
    本文介绍了PHP设置MySQL字符集的方法,详细介绍了使用mysqli_set_charset函数来规定与数据库服务器进行数据传送时要使用的字符集。通过示例代码演示了如何设置默认客户端字符集。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • Centos下安装memcached+memcached教程
    本文介绍了在Centos下安装memcached和使用memcached的教程,详细解释了memcached的工作原理,包括缓存数据和对象、减少数据库读取次数、提高网站速度等。同时,还对memcached的快速和高效率进行了解释,与传统的文件型数据库相比,memcached作为一个内存型数据库,具有更高的读取速度。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 解决VS写C#项目导入MySQL数据源报错“You have a usable connection already”问题的正确方法
    本文介绍了在VS写C#项目导入MySQL数据源时出现报错“You have a usable connection already”的问题,并给出了正确的解决方法。详细描述了问题的出现情况和报错信息,并提供了解决该问题的步骤和注意事项。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
author-avatar
陈玲琳2013
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有