热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

oracle表联结的方法

oracle表联结的方法联结的方法有:嵌套循环联结、散列联结、排序-合并联结、笛卡儿积联结。每种联结方法都有一定的最适合使用的条件,对于每对需要联结的表,优化器还必须确定表联结的顺序。嵌套循环联结(NESTE...SyntaxHighlighter.all();

oracle表联结的方法
 
 联结的方法有:嵌套循环联结、散列联结、排序-合并联结、笛卡儿积联结。每种联结方法都有一定的最适合使用的条件,对于每对需要联结的表,优化器还必须确定表联结的顺序。
 
嵌套循环联结(NESTED LOOPS)
   www.2cto.com  
嵌套循环联结使用一次访问运算所得到的结果集中每一行来与另一个表进行对碰。如果结果集的大小是有限的,并且在用来联结的列上建有索引的话,这种联结的效率通常是最高的。嵌套循环联结的运算成本主要是读取外层表中的每一行并将其与所匹配的内层表中的行联结所需的成本。
 
顾名思义,嵌套循环联结就是一个循环嵌套在另一个循环当中。外层循环基本来说就是一个只使用WHERE子句中的属于驱动表的条件对它进行的查询。当数据行经过了外层条件筛选并被确认匹配条件后,这些行就会逐个进入到内层循环中。然后再基于联结列进行逐行检查看是否与被联结的表中的某一行相匹配。如果这一行与第二次的检查相匹配,就将会被传递到查询计划的下一步或者如果没有更多步骤的话直接被包含在最终的结果集中。这种类型的强大之处在于所使用的内存是非常少的 。在结果集较少的时候会是最好的。NESTED LOOPS运算后所列出的第一个表是驱动表。
   www.2cto.com  
排序-合并联结(SORT JOIN MERGE JOIN)
 
      排序-合并联结独立地读取需要联结的两张表,对每张表中的数据行按照联结键进行排序,然后对排序后的数据行集进行行合并。对这种联结方法来说排序的开销是非常大的。对于不能够放入内存中的大的数据源来说,可能会使用临时磁盘空间来完成排序。这是非常耗占内存和时间资源的。但是一但数据行集排序完成了,合并的过程是非常快的。为了进行合并,数据库轮流操作两个表,经较最上面的数据行,丢弃在排序队列中比另一列表中的最上面一行出现得早的数据行,并只返回匹配的行。
 
散列联结(HASH JOIN)
 
     散列联结,与排序-合并联结类似,首先应用WHERE子句中的筛选标准来独立地读取要进行联结的两个表。基于表和索引的统计信息,被确定为返回最少行数的表被完全散列化到内存中。这个散列表包含了原表的所有数据行并被基于将联结键转化为散列值的随机函数载入到散列桶中。只要有足够的内存空间,这个散列表将一直放在内存中。然而,如果没有足够的内存,散列表将会被写入到临时磁盘空间。
 
     下一步就是读取另一张较大的表并对联结键列应用散列函数。然后利用得到的散列值,对较小的在内存中的散列表进行探测以寻找匹配的第一个表的行数据所在的散列桶。每个散列桶都有一个放在其中的数据行列表(通过一个位图来表示)。这个列表被用来与探测行进行匹配。如果匹配成功,则返回这一行数据,否则丢弃。  www.2cto.com  
 
较大的表只读取一次,并检查其中的每一行来寻找匹配。这与嵌套循环联结的不同之处在于,此处内层表被多次读取。因此较大的表是驱动表,仅读取一次,而较小的散列表则被探测很多次。与嵌套回路联结执行计划不同,在执行计划的输出中较小的散列表放在前面而较大的探测表放在后面。
 
笛卡尔积联结(MERGE JOIN CARTESIAN)
 
      笛卡尔联结发生在当一张表中的所有行与另一张表中的所有行联结的时候。因此,这种联结所得到的结果集的部行数等于一张表(A)中的数据行数乘以另一张表(B)中的数据行数,也就是A*B=结果集中总的数据行数。
 
外联结(NESTED LOOPS OUTER)
 
      外联结返回一张表的所有行以及另一张表中满足联结条件的行数据。ORACLE使用+字符来表明进行外联结。+号放在一对圆括号中,位于只有匹配才会返回数据行的表联结旁。正如在对种联结方法进行总述的时候指出的,外联结需要外联结表作为驱动表。这意味着有可能不能选用更加优化的联结执行顺序。因此,使用外联结的时候需要格外小心,因为它的选用有可能会影响到整个执行计划的性能。  www.2cto.com  
 
     小结:在确定SQL语句的执行计划的时候,优化器必须做出几个关键的选择。首先,要确定查询中所用的每个表最合适的访问方法。基本上有两种选择:索引扫描 或全表扫描 。每种访问方法用来访问包含SQL语句所需数据的实现方式是不同的。一旦优化器选定了访问方法,就必须选定联结方法。
 
表将会被逐对进行联结,前一次联结的结果的数据行被用来与下一个表进行联结,直到所有表都被联结并获得最终的结果集。理解每种访问和联结方法是如何实现,有助于你写出可以让优化器作出最高效选择的SQL。理解所选的运算以及这些运算是如何进行,也将助于你来避免最容易发生性能问题的地方。理解表之下的内部原理,可以帮助你写出更好、更快的SQL语句。
 

推荐阅读
  • 本文介绍了如何在MySQL中将零值替换为先前的非零值的方法,包括使用内联查询和更新查询。同时还提供了选择正确值的方法。 ... [详细]
  • 本文介绍了如何使用Power Design(PD)和SQL Server进行数据库反向工程的方法。通过创建数据源、选择要反向工程的数据表,PD可以生成物理模型,进而生成所需的概念模型。该方法适用于SQL Server数据库,对于其他数据库是否适用尚不确定。详细步骤和操作说明可参考本文内容。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • MyBatis错题分析解析及注意事项
    本文对MyBatis的错题进行了分析和解析,同时介绍了使用MyBatis时需要注意的一些事项,如resultMap的使用、SqlSession和SqlSessionFactory的获取方式、动态SQL中的else元素和when元素的使用、resource属性和url属性的配置方式、typeAliases的使用方法等。同时还指出了在属性名与查询字段名不一致时需要使用resultMap进行结果映射,而不能使用resultType。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文介绍了通过mysql命令查看mysql的安装路径的方法,提供了相应的sql语句,并希望对读者有参考价值。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
author-avatar
紫百合1990_950
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有