oracle 联结方法

一般来说,联结方法分为:嵌套循环联结(Nested Loops),散列联结(Hash-Join),排序合并联结(Sort Merge Join)以及笛卡尔联结(Merge Join Cartesian).

1、嵌套循环联结(Nested Loops)

嵌套循环有外部表(drivingtable,驱动表)和内部表(inner或driven-to table ,被驱动表)的概念,一般来说,结果集大的成为内部表,结果集小的成为外部表。由外部表(结果集)来驱动内部表。

嵌套循环联结使用一次访问运算所得的结果集(外部表)中的每一行来与另一个表(内部表)进行对碰。如果结果集的大小是有限的并且在用来联结的列(inner table 的列)上有索引的话,这种联结的效率通常是最高的。

简而言之,这种类型的联结,如果外部表(结果集)非常小,而内部表(结果集)非常大并且已预先建立索引,那么嵌套循环联接将特别有效率。

优缺点:使用内存非常小,因为不排序,且数据行集一次只加工一行,所需的开支非常小。也正是这个原因,除了建立一个大数据集所花的时间较长这一点之外,它也是适合进行大数据集加工的。

嵌套循环联结的基本度量是为了准备最终结果集所需要访问的数据块数目。

2、排序合并联结(Sort Merge Join)

内部连接过程:

 1) 首先生成 rowsource1 需要的数据,然后对这些数据按照连接操作关联列(如 A.col3 )进行排序。

 2) 随后生成 rowsource2 需要的数据,然后对这些数据按照与 sort source1 对应的连接操作关联列(如 B.col4 )进行排序。

 3) 最后两边已排序的行被放在一起执行合并操作,即将 2 个 row source 按照连接条件连接起来

  下面是连接步骤的图形表示:

                   MERGE

                /           /

          SORT             SORT

            |                |

   Row Source1          Row Source 2

如果 row source已经在连接关联列上被排序,则该连接操作就不需要再进行 sort 操作,这样可以大大提高这种连接操作的连接速度,因为排序是个极其费资源的操作,特别是对于较大的表。预先排序的 row source 包括已经被索引的列(如 a.col3 或 b.col4 上有索引)或 row source 已经在前面的步骤中被排序了。尽管合并两个 row source 的过程是串行的,但是可以并行访问这两个 row source (如并行读入数据,并行排序)。一旦数据集排序完成了,合并过程是非常快的。

排序合并联结一般最适合于数据筛选条件有限并返回有限数据行的查询。若关联列没有可用的索引时,排序合并联结也通常是较好的选择。

总的来说,在条件为非等值式的时候,排序合并联结通常是最好的选择。列如:where table1.col1 between table2.col1 and table2.col2  ,这样的连接条件就较适合排序合并联结。(这种情况散列联结是不可能的)

如果数据行源非常大,排序合并联结就可能是唯一可行的选择。

3、散列联结(Hash-Join,哈希联结)

这种联结是在 oracle7.3 以后引入的,从理论上来说比 NL(嵌套循环) 与 SMJ(排序合并) 更高效,而且只用在 CBO 优化器中。

首先应用where条件的筛选标准来读取要进行联结的两个表,基于表和索引的统计信息,确定小的结果集并完全散列化到内存中。这个散列表包含了源结果集的所有数据行,并被联结键转化为散列值的随机函数载入到散列桶中。只要内存充足,这个散列表一直保存在内存中,若内存不足,则写到磁盘。

然后就是读取大结果集并对联结键列应用散列函数。

 较小的 rowsource 被用来构建 hash table 与 bitmap ,第 2 个 row source 被用来被 hansed ,并与第一个 row source 生成的 hash table 进行匹配,以便进行进一步的连接。 Bitmap 被用来作为一种比较快的查找方法,来检查在 hash table 中是否有匹配的行。特别的,当 hash table 比较大而不能全部容纳在内存中时,这种查找方法更为有用。这种连接方法也有 NL连接中所谓的驱动表的概念,被构建为 hash table 与 bitmap 的表为驱动表,当被构建的 hash
table 与 bitmap 能被容纳在内存中时,这种联结方式的效率极高。

要使哈希连接有效,需要设置 HASH_JOIN_ENABLED=TRUE ,缺省情况下该参数为 TRUE ,另外,不要忘了还要设置 hash_area_size 参数,以使哈希连接高效运行,因为哈希连接会在该参数指定大小的内存中运行,过小的参数会使哈希连接的性能比其他连接方式还 要低。

注意:决定哪个表是最小的不仅取决于数据行数,还取决于这些行的大小,因为整个行都会存放在散列表中。

最后,总结一下,在哪种情况下用哪种连接方法比较好:

  排序 合并联结( SortMerge Join , SMJ ):

   a ) 对于非等值连接,这种连接方式的效率是比较高的。

   b ) 如果在关联的列上都有索引,效果更好。

   c ) 对于将 2 个较大的 rowsource 做连接,该连接方法比 NL 连接要好一些。

   d ) 但是如果 sortmerge 返回的 row source 过大,则又会导致使用过多的 rowid 在表中查询数据时,数据库性能下降,因为过多的 I/O.

  嵌套循环( NestedLoops , NL ):

   a ) 如果 drivingrow source (外部表)比较小,并且在 inner row source (内部表)上有唯一索引,或有高选择性非唯一索引时,使用这种方法可以得到较好的效率。

   b ) NESTEDLOOPS 有其它连接方法没有的的一个优点是:可以先返回已经连接的行,而不必等待所有的连接操作处理完才返回数据,这可以实现快速的响应时间。

  哈希联结( HashJoin , HJ ):

   a ) 这种方法是在 oracle7 后来引入的,使用了比较先进的连接理论,一般来说,其效率应该好于其它 2 种连接,但是这种连接只能用在 CBO 优化器中,而且需要设置合适的 hash_area_size 参数,才能取得较好的性能。

   b ) 在 2 个较大的 rowsource 之间连接时会取得相对较好的效率,在一个 row source 较小时则能取得更好的效率。

   c ) 只能用于等值连接中

d )对索引不要求(有索引也可能走索引,它不会限制sql是访问方式)

时间: 2024-10-07 03:36:39

oracle 联结方法的相关文章

php操作oracle的方法类集全

在网上开始找php中操作oracle的方法类~ 果然找到一个用php+oracle制作email表以及插入查询的教程,赶忙点开来看,从头到尾仔细的看了一遍,还没开始操作,便觉得收获很大了.地址在此:http://www.alixixi.com/program/a/2008050731615.shtml#replay. http://blog.163.com/[email protected]/blog/static/27712393201131815035122/        (博客校园) 摘

PL/SQLDeveloper导入导出Oracle数据库方法

前一篇博客介绍了Navicat工具备份Oracle的方法,这篇博客介绍一下使用PL/SQL Developer工具导入导出Oracle数据库的方法. PL/SQL Developer是Oracle数据库用于导入导出数据库的主要工具之一,本文主要介绍利用PL/SQL导入导出Oracle数据库的过程. 1.Oracle数据库导出步骤 1.1 Tools→Export User Objects...选项,导出.sql文件. 说明:此步骤导出的是建表语句(包括存储结构). 1.2 Tools→Expor

Oracle 笔记:PLSQL无法连接64位Oracle 解决方法

Plsql打开后提示错误,登录界面无连接目标选择. 原因:PLSQL本身好像就不支持64位的Oracle. 解决方法: 到Oracle 官网下载32位的 Oracle 客户端,地址为 http://www.oracle.com/technetwork/topics/winsoft-085727.html 解压下载的32位客户端即可. PLSQL登录界面暂时取消登录,先进入PLSQL界面,点击首选项,设置OCI库为刚才下载的32位客户端的OCI路径,路径中一定要包含 oci.dll . 添加环境变

java程序通过jdbc连接oracle数据库方法

1.  赋予scott用户连接权限:Grant connect to scott: 2.   在Myeclipse中新建java项目导入jdbc包(classes12.jar):        右键项目 bulid path -〉add external archives 选择classes12.jar 3.   新建java文件, lianxi01.java import java.sql.Connection; import java.sql.ResultSet; import java.s

PL/SQL Developer导入导出Oracle数据库方法

前一篇博客介绍了Navicat工具备份Oracle的方法,这篇博客介绍一下使用PL/SQL Developer工具导入导出Oracle数据库的方法. PL/SQL Developer是Oracle数据库用于导入导出数据库的主要工具之一,本文主要介绍利用PL/SQL导入导出Oracle数据库的过程. 1.Oracle数据库导出步骤 1.1 Tools→Export User Objects...选项,导出.sql文件. 说明:此步骤导出的是建表语句(包括存储结构). 1.2 Tools→Expor

查看及修改Oracle编码格式方法

 首先查看oracle数据库的编码 SQL> select * from nls_database_parameters where parameter ='NLS_CHARACTERSET'; PARAMETER -------------------- VALUE -------------------- NLS_CHARACTERSET AL32UTF8 这其来源于props$,这是表示数据库的字符集. oracle客户端编码 SQL> select * from nls_insta

.NET连接Oracle的方法

方式1:直接利用.NET的oracle驱动连接 引用System.data.oracleclient; using System.data.oracleclient; string oradb = "Data Source=water;User Id=modis;Password=modis;Integrated Security=no"; OracleConnection conn = new OracleConnection(oradb); conn.Open();     方式2

新建Oracle数据库方法

新建Oracle数据库三种方法:1.通过运行Oracle Database Configuration Assistant 创建配置或删除数据库(也可在命令行下输入dbca):2.用命令行的方式建立数据库3.通过运行自定义的批处理脚本(或create_ORACLE_SID.bat(create_ORACLE_SID.sql))来创建配置或删除数据库详述:1.通过运行Oracle Database Configuration Assistant 创建配置或删除数据库: 建议不熟悉创建过程的DBA使

解决中64位Win7系统上PLSQL无法连接ORACLE的方法(PLSQL无法识别ORACLE_HOME的配置)

最近新安装了64位的Win7系统,工作中需要用oracle数据库,而数据库是公司IT的DBA进行管理和维护的. 我们只需要连接上去进行使用就可以了,于是我就在自己的机器上安装了oracle client x64和PL/SQL程序,oracle client也设置了环境变量等配置,但打开plsql的时候无法显示数据库,效果如下图: 于是,我自己到网上查了一下,网上说法很多,如下说明. 1.问题 Plsql到目前为止只有32位的程序,而大多数的桌面系统基本都是使用64位的windows操作系统,在6