`
liulanghan110
  • 浏览: 1077985 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

表连接的原理

 
阅读更多

当一个查询请求涉及到数据库的多个表时,必须用一定的连接条件或连接谓词将这些表连接起来,才能提供用户需要的信息

常用的表连接方式:

a.    嵌套循环连接(Nested Loop b. 排序合并连接(Sort Merge) c. 哈希连接(Hash join

嵌套循环连接( Nested Loop

代码如下:

	/*
 	* 嵌套循环连接( Nested Loop )
 	* tableA :驱动表 (小表) tableB 被驱动表  result结果
 	*/
	public void NestedLoop(List<A> tableA,List<B> tableB,List<Integer> result){
		for(A a :tableA){
			for(B b :tableB){
				if(a.getId().equals(b.getId())){
					result.add(a.getId());
				}
			}
		}
	}

 

 

嵌套循环连接的工作方式是这样的:

1 Oracle 首先选择一张表作为连接的驱动表,这张表也称为外部表(Outer Table )。由驱动表进行驱动连接的表或数据源称为内部表(Inner Table )。

2 、提取驱动表中符合条件的记录,与被驱动表的连接列进行关联查询符合条件的记录。在这个过程中,Oracle 首先提取驱动表中符合条件的第一条记录,再与内部表的连接列进行关联查询相应的记录行。在关联查询的过程中,Oracle 会持续提取驱动表中其他符合条件的记录与内部表关联查询。这两个过程是并行进行的,因此嵌套循环连接返回前几条记录的速度是非常快的。在这里需要说明的是,由于Oracle 最小的IO 单位为单个数据块(BLOCK),因此在这个过程中Oracle 会首先提取驱动表中符合条件的单个数据块中的所有行,再与内部表进行关联连接查询的,然后提取下一个数据块中的记录持续地循环连接下去。当然,如果单行记录跨越多个数据块的话,就是一次单条记录进行关联查询的。

3 、嵌套循环连接里面存在着两个循环,一个是外部循环,提取驱动表中符合条件的每条记录。另外一个是内部循环,根据外循环中提取的每条记录对内部表进行连接查询相应的记录。由于这两个循环是嵌套进行的,故此种连接方法称为嵌套循环连接。

嵌套循环连接适用于查询的选择性强、约束性高并且仅返回小部分记录的结果集。通常要求驱动表的记录(符合条件的记录,通常通过高效的索引访问)较少,且被驱动表连接列有唯一索引或者选择性强的非唯一索引时,嵌套循环连接的效率是比较高的。

嵌套循环连接驱动表的选择也是连接中需要着重注意的一点,有一个常见的误区是驱动表要选择小表,其实这是不对的。假如有两张表A B 关联查询,A 表有1000000 条记录,B 表有10000 条记录,但是A 表过滤出来的记录只有10 条,这时候显然用A 表当做驱动表是比较合适的。因此驱动表是由过滤条件限制返回记录最少的那张表,而不是根据表的大小来选择的。

在外连接查询中,如果走嵌套循环连接的话,那么驱动表必然是没有符合条件关联的那张表,也就是 A left join B中的A。这是由于外连接需要提取可能另一张表没符合条件的记录,因此驱动表需要是那张我们要返回所有符合条件记录的表。

嵌套循环连接返回前几行的记录是非常快的,这是因为使用了嵌套循环后,不需要等到全部循环结束再返回结果集,而是不断地将查询出来的结果集返回。在这种情况下,终端用户将会快速地得到返回的首批记录,且同时等待Oracle 内部处理其他记录并返回。如果查询的驱动表的记录数非常多,或者被驱动表的连接列上无索引或索引不是高度可选的情况,嵌套循环连接的效率是非常低的。

 

排序合并连接(Sort Merge)

嵌套循环连接也就是双重FOR循环,对被驱动表(内层表)将重复扫描很多次。为了解决这个问题,可以使用排序合并连接

/*
	 *  排序合并连接(Sort Merge) 
	 * tableA :表A tableB 表B  result结果
	 */
	public void SortMerge(List<A> tableA,List<B> tableB,List<Integer> result){
		Sort(tableA);
		Sort(tableB);
		for(int i = 0,j = 0;i < tableA.size()&&j < tableB.size();){
			if(tableA.get(i).getId() > tableB.get(j).getId()){
				j++;
			}else if(tableA.get(i).getId() < tableB.get(j).getId()){
				i++;
			}else{
				result.add(tableA.get(i).getId());
				i++;
				j++;
			}
		}
		
	}

 

 

 

由上面的算法可以看出,排序合并连接并没有驱动表和被驱动表的概念。两个互相连接的表按连接列的值先排序,排序完后形成的结果集再互相进行合并连接提取符合条件的记录。这样可以避免多次扫描表。可排序是在内存中进行的,所以排序合并连接需要占用内存,也就是ORALCE中的排序空间(PGA排序区)如果PGA中特定的排序大小(pga_aggregat_target:sort_area_size)不足以进行排序操作,也就是说需要排序分组的数据集合特别大的时候,Oracle需要调用Temp表空间的容量来进行操作。这也就是问题的所在。Temp表空间数据存储位于磁盘中,速度与内存相差很多。所以,当进行排序操作的数据集合很大,会出现性能急剧的下降可能。

在嵌套循环中,对连接列进行索引处理,可以很大程度上提升执行计划效率,减少随机读的数量。而排序合并连接却不能有效的利用索引,即使连接列上存在索引,一般也不会被采用。

总的来说,嵌套循环连接适用于较小的数据量的情况。而排序合并连接适用于较大数据量的情况,而当数据量很大时,排序合并连接会产生排序溢出(sort flow),导致硬盘排序,性能会急剧下降。

  

哈希连接( Hash join

哈希连接类似代码如下:

/*
	 *  哈希连接( Hash join ) 
	 * tableA :表A tableB 表B  result结果
	 */
	public void HashJoin(List<A> tableA,List<B> tableB,List<Integer> result){
		HashTable hashTable = Hash(tableA);
		Integer[] hashTable = new Integer[];
		for(A a:tableA){
			hashTable.add(Hash(a.getId()));
		}
		
		for(B b:tableB){
			if(hashTable[Hash(b.getId())]!=null){ 
				
			}
		}
	}

 

 

有上面的代码可以看出,哈希连接主要过程如下:

构建阶段:优化器首先选择一张小表做为驱动表,运用哈希函数对连接列进行计算产生一张哈希表。通常这个步骤是在内存(hash_area_size )里面进行的,因此运算很快。

探测阶段:优化器对被驱动表的连接列运用同样的哈希函数计算得到的结果与前面形成的哈希表进行探测返回符合条件的记录。这个阶段中如果被驱动表的连接列的值没有与驱动表连接列的值相等的话,那么这些记录将会被丢弃

在大数据量时,排序合并连接会产生排序溢出。可是哈希连接只会用小表的连接列构建一个哈希表,所用内存不多,不会发生排序溢出。所以在大数据量时,采用哈希连接会更好。但由于哈希算法所特有的特点,哈希连接只适用于等值连接。

 

 

分享到:
评论

相关推荐

    SQL多表连接

    本文档为通用SQL数据库查询时所用,讲述的是多表连接!~

    jdbc连接池原理

    关于jdbc连接池连接数据库的原理

    超声波热量表-原理图

    6. **外部接口**:原理图中还包含了多个用于连接外部设备的接口,如J1、J2、J3、J4、J5,这些接口可能用于连接传感器、电源或其他外部控制系统,增强了设备的扩展性和实用性。 7. **电源管理**:原理图中还包括了...

    智能燃气表原理图PCB和库文件

    原理图是电子设计的基础,它清晰地描绘了各个元器件的连接方式和工作关系,帮助工程师理解系统的工作流程。使用Protel 99SE设计的这份原理图,可以为电路分析、故障排查以及硬件修改提供依据。 PCB(Printed ...

    连接池的基本工作原理

    【连接池的基本工作原理】 连接池是数据库管理中一种重要的技术,它的主要目的是优化数据库连接的使用,提高系统性能和资源利用率。连接池的核心思想是通过维持一个预创建的数据库连接池,使得应用程序在需要时可以...

    几种常用的表连接方式

    本文将深入探讨四种常用的表连接方式:嵌套循环连接、排列合并连接、哈希连接以及索引连接,并详细阐述每种连接方式的工作原理、适用场景及其优缺点。 #### 1. 嵌套循环连接(Nested Loop Join) 嵌套循环连接是最...

    收藏各种常用万用表电路原理图

    压缩包内的文件名列表提供了各个万用表的电路图文件,如“FS970X.gif、VC9808.gif”等,这些文件通常会展示电路的连接方式、关键元器件的位置以及信号流程,对于学习和分析非常有用。例如,“FS970X.gif”可能展示了...

    三相表安装原理图

    在三相表安装原理图中,3p3pBLV 6平方BV2.52p2p2p1pA插座表示三相四线制(3P4W)的连接方式,其中“3p”代表三相,“3pBLV”指的是三相无接地线的电缆,6平方毫米的截面积则意味着电缆的粗细。BV2.52p2p2p1p则可能...

    VPX连接器J1原理图和PCB封装

    标题“VPX连接器J1原理图和PCB封装”暗示了该压缩包包含的是关于VPX连接器系列中的J1型号的电气原理图和印刷电路板(PCB)布局文件。原理图是电子设计自动化(EDA)过程的关键部分,它以图形方式展示了各个电子元件...

    VPX连接器P0原理图和PCB封装

    在"VPX连接器P0原理图和PCB封装"的资料中,我们主要关注两个关键部分:原理图(Schematic)和PCB封装(Package)。 1. **VPX连接器P0原理图**: 原理图是电路设计的基础,它展示了各个电子元件如何通过导线或信号...

    自制电感表原理图与源码

    本项目提供了自制电感表的原理图和源码,帮助用户理解其工作原理,并可据此制作自己的电感测量设备。 首先,电感表的基本工作原理基于电磁感应定律。当一个交流信号通过一个电感器时,其电压与电流之间的相位差可以...

    MT6261_GPS定位儿童手表原理图.rar

    MT6261 GPS定位儿童手表的原理涉及到无线通信、GPS定位、WIFI连接等多个技术领域,通过联发科的这款芯片,儿童手表实现了高效、精准的功能。通过深入理解MT6261芯片及其相关原理图,不仅可以了解儿童手表的工作机制...

    CC2530和CC2952连接原理图

    在深入理解CC2530和CC2952的连接原理图之前,我们需要了解它们所应用的领域。CC2530是一款由德州仪器(Texas Instruments,简称TI)公司生产的ZigBee/IEEE 802.15.4系统单芯片解决方案,广泛应用于低功耗无线通信...

    数据库连接池的图解原理

    本文将详细解释数据库连接池的图解原理,帮助你理解这一技术的核心概念。 首先,我们需要理解什么是数据库连接。数据库连接是应用程序与数据库之间建立的通信通道,用于执行SQL查询和获取数据。然而,频繁地创建和...

    VPX连接器RP1原理图和PCB封装

    本资料包含“VPX连接器RP1原理图”和“PCB封装”,这两个文档都是以Cadence格式提供的,这是一种专业且功能强大的电子设计自动化(EDA)软件工具。Cadence 16.6版本能够顺利打开这些文件,意味着它们遵循了最新的...

    CDL网表导出原理图的详细操作及实例.pdf

    在导入CDL网表的过程中,Virtuoso能够将网表中的描述转换为对应的电路组件与连接关系,进而形成可进一步编辑和操作的原理图。 知识点3:导入CDL网表的操作步骤 文档中描述了具体的步骤来导入CDL网表,这些步骤包括...

    DM9000A与网络变压器连接原理图

    DM9000A与HR601680连接原理图

    amp d3100连接器原理图、封装库

    标题中的“原理图”是指AMP D3100连接器的电气布局图,它展示了连接器内部引脚的排列和功能,以及如何与外部电路连接。工程师在设计电路时会使用这种原理图来确定连接器的正确使用方式,确保信号和电源能正确传输。...

Global site tag (gtag.js) - Google Analytics