一表的连接

表的连接是指在一个SQL语句中通过表与表之间的关联,从一个或多个表检索出相关的数据。连接是通过SQL语句中FROM从句的多个表名,以及WHERE从句里定义的表之间的连接条件来实现的。如果一个SQL语句的关联表超过两个,那么连接的顺序如何呢?ORACLE首先连接其中的两个表,产生一个结果集;然后将产生的结果集与下一个表再进行关联;继续这个过程,直到所有的表都连接完成;最后产生所需的数据。下面都以两个表的连接为例

create table user_info(user_name char(10),user_id char(10));

create table dev_info(dev_no char(10),user_id char(10),dev_type char(10));

说明和分析表的各种连接方式。

ORACLE从6的版本开始,优化器使用4种不同的表的连接方式:

Ø嵌套循环连接(NESTED LOOP JOIN)

Ø群集连接(CLUSTER JOIN)

Ø排序合并连接(SORT MERGE JOIN)

Ø笛卡尔连接(CARTESIAN JOIN)

ORACLE 7.3中,新增加了

Ø哈希连接(HASH JOIN)。

在ORACLE 8中,新增加了

Ø索引连接(INDEX JOIN)。

这六种连接方式都有其独特的技术特点,在一定的条件下,可以充分发挥高效的性能。

但是也都有其局限性,如果使用不当,不仅不能提高效率,反而会严重影响系统的性能。因此,深入地探讨连接方式的内部运行机制对于性能优化是必要的。

1嵌套循环连接

嵌套循环连接的内部处理的流程:

1)Oracle优化器根据基于规则RBO或基于成本CBO的原则,选择两个表中的一个作为驱动表,并指定其为外部表。

2)Oracle优化器再将另外一个表指定为内部表。

3)Oracle从外部表中读取第一行,然后和内部表中的数据逐一进行对比,所有匹配的记录放在结果集中。

4)Oracle读取外部表中的第二行,再和内部表中的数据逐一进行对比,所有匹配的记录添加到结果集中。

5)重复上述步骤,直到外部表中的所有纪录全部处理完。

6)最后产生满足要求的结果集。

通过查询SQL语句的执行计划可以看出哪个表是外部表,哪个为内部表。

如 select a.user_name,b.dev_no

from user_info a, dev_info b

where a.user_id = b.user_id;

的执行计划:

SELECT STATEMENT ptimizer=CHOOSE

NESTED LOOPS

TABLE ACCESS (FULL) OF 'USER_INFO' --驱动表,外部表

TABLE ACCESS (FULL) OF 'DEV_INFO'  --内部表

使用嵌套循环连接是一种从结果集中提取第一批记录最快速的方法。在驱动行源表(就是正在查找的记录)较小、或者内部行源表已连接的列有惟一的索引或高度可选的非惟一索引时,嵌套循环连接效果是比较理想的。嵌套循环连接比其他连接方法有优势,它可以快速地从结果集中提取第一批记录,而不用等待整个结果集完全确定下来。这样,在理想情况下,终端用户就可以通过查询屏幕查看第一批记录,而在同时读取其他记录。不管如何定义连接的条件或者模式,任何两行记录源可以使用嵌套循环连接,所以嵌套循环连接是非常灵活的。

然而,如果内部行源表(读取的第二张表)已连接的列上不包含索引,或者索引不是高度可选时,嵌套循环连接效率是很低的。如果驱动表的记录非常庞大时,其他的连接方法可能更加有效。

可以通过在SQL语句中添加HINTS,强制ORACLE优化器产生嵌套循环连接的执行计划。

select /*+ use_nl(a b) */ a.user_name,b.dev_no

from user_info a, dev_info b

where a.user_id = b.user_id;

2群集连接(CLUSTER JOIN)

群集连接实际上是嵌套循环连接的一种特例。如果所连接的两张源表是群集中的表,即两张表属于同一个段(SEGMENT),,那么ORACLE能够使用群集连接。处理的过程是:ORACLE从第一张行源表中读取第一行,然后在第二张行源表中使用CLUSTER索引查找能够匹配到的纪录;继续上面的步骤处理行源表中的第二行,直到所有的记录全部处理完。

群集连接的效率极高,因为两个参加连接的行源表实际上处于同一个物理块上。但是,群集连接也有其限制,没有群集的两个表不可能用群集连接。所以,群集连接实际上很少使用。

3排序合并连接(SORT MERGE JOIN)

排序合并连接内部处理的流程:

1)优化器判断第一个源表是否已经排序,如果已经排序,则到第3步,否则

到第2步。

2)第一个源表排序

3)优化器判断第二个源表是否已经排序,如果已经排序,则到第5步,否则

到第4步。

4)第二个源表排序

5)已经排过序的两个源表进行合并操作,并生成最终的结果集。

在缺乏数据的选择性或者可用的索引时,或者两个源表都过于庞大(所选的数据超过表记录数的5%)时,排序合并连接将比嵌套循环连更加高效。

排列合并连接需要比较大的临时内存块,以用于排序,这将导致在临时表空间占用更多的内存和磁盘I/O。

select a.user_name,b.dev_no

from user_info a, dev_info b

where a.user_id > b.user_id;

Plan

--------------------------------------------------

SELECT STATEMENT ptimizer=CHOOSE (Cost=7 Card=336 Bytes=16128)

MERGE JOIN (Cost=7 Card=336 Bytes=16128)

SORT (JOIN) (Cost=4 Card=82 Bytes=1968)

TABLE ACCESS (FULL) OF 'USER_INFO' (Cost=2 Card=82 Bytes=1968)

SORT (JOIN) (Cost=4 Card=82 Bytes=1968)

TABLE ACCESS (FULL) OF 'DEV_INFO' (Cost=2 Card=82 Bytes=1968)

可以通过在SQL语句中添加HINTS,强制ORACLE优化器产生排序合并连接的执行计划。

select /*+ use_merge(a b) */ a.user_name,b.dev_no

from user_info a, dev_info b

where a.user_id > b.user_id;

排序合并连接是基于RBO的。

4笛卡尔连接(CARTESIAN JOIN)

笛卡尔连接是指在sql语句中没有写出表连接的条件,优化器把第一个表的每一条记录和第二个表的所有纪录相连接。如果第一个表的纪录数为m,第二个表的纪录数为m,则会产生m*n条纪录数。

下面的查询,未指名连接条件,就会产生笛卡尔连接。

select a.user_name,b.dev_no

from user_info a ,dev_info b;

由于笛卡尔连接会导致性能很差的SQL,因此一般也很少用到。

5哈希连接

当内存能够提供足够的空间时,哈希(HASH)连接是Oracle优化器通常的选择。哈希连接中,优化器根据统计信息,首先选择两个表中的小表,在内存中建立这张表的基于连接键的哈希表;优化器再扫描表连接中的大表,将大表中的数据与哈希表进行比较,如果有相关联的数据,则将数据添加到结果集中。

当表连接中的小表能够完全cache到可用内存的时候,哈希连接的效果最佳。哈希连接的成本只是两个表从硬盘读入到内存的成本。

但是,如果哈希表过大而不能全部cache到可用内存时,优化器将会把哈希表分成多个分区,再将分区逐一cache到内存中。当表的分区超过了可用内存时,分区的部分数据就会临时地写到磁盘上的临时表空间上。因此,分区的数据写磁盘时,比较大的区间(EXTENT)会提高I/O性能。ORACLE推荐的临时表空间的区间是1MB。临时表空间的区间大小由UNIFORM. SIZE指定。

当哈希表构建完成后,进行下面的处理:

1)第二个大表进行扫描

2)如果大表不能完全cache到可用内存的时候,大表同样会分成很多分区

3)大表的第一个分区cache到内存

4)对大表第一个分区的数据进行扫描,并与哈希表进行比较,如果有匹配的纪录,添加到结果集里面

5)与第一个分区一样,其它的分区也类似处理。

6)所有的分区处理完后,ORACLE对产生的结果集进行归并,汇总,产生最终的结果。

当哈希表过大或可用内存有限,哈希表不能完全CACHE到内存。随着满足连接条件的结果集的增加,可用内存会随之下降,这时已经CACHE到内存的数据可能会重新写回到硬盘去。如果出现这种情况,系统的性能就会下降。

当连接的两个表是用等值连接并且表的数据量比较大时,优化器才可能采用哈希连接。哈希连接是基于CBO的。只有在数据库初始化参数HASH_JOIN_ENABLED设为True,并且为参数PGA_AGGREGATE_TARGET设置了一个足够大的值的时候,Oracle才会使用哈希边连接。HASH_AREA_SIZE是向下兼容的参数,但在Oracle9i之前的版本中应当使用HASH_AREA_SIZE。当使用ORDERED提示时,FROM子句中的第一张表将用于建立哈希表。

selecta.user_name,b.dev_no

from user_info a, dev_info b

where a.user_id = b.user_id;

Plan

----------------------------------------------------------

0SELECT STATEMENT ptimizer=CHOOSE (Cost=5 Card=82 Bytes=3936

)

10HASH JOIN (Cost=5 Card=82 Bytes=3936)

21TABLE ACCESS (FULL) OF 'USER_INFO' (Cost=2 Card=82 Bytes

=1968)

31TABLE ACCESS (FULL) OF 'DEV_INFO' (Cost=2 Card=82 Bytes=

1968)

可以通过在SQL语句中添加HINTS,强制ORACLE优化器产生哈希连接的执行计划。

select /*+ use_hash(a b)*/ a.user_name,b.dev_no

from user_info a, dev_info b

where a.user_id = b.user_id;

当缺少有用的索引时,哈希连接比嵌套循环连接更加有效。哈希连接也可能比嵌套循环连接更快,因为处理内存中的哈希表比检索B_树索引更加迅速。

6索引连接

如果一组已存在的索引包含了查询所需要的所有信息,那么优化器将在索引中有选择地生成一组哈希表。可通过范围或者快速全局扫描访问到每一个索引,而选择何种扫描方式取决于WHERE子句中的可有条件。在一张表有大量的列,而您只想访问有限的列时,这种方法非常有效。WHERE子句约束条件越多,执行速度越快。因为优化器在评估执行查询的优化路径时,将把约束条件作为选项看待。您必须在合适的列(那些满足整个查询的列)上建立索引,这样可以确保优化器将索引连接作为可选项之一。这个任务通常牵涉到在没有索引,或者以前没有建立联合索引的列上增加索引。相对于快速全局扫描,连接索引的优势在于:快速全局扫描只有一个单一索引满足整个查询;索引连接可以有多个索引满足整个查询。

假设表dev_info上有两个索(一个在dev_no,一个在dev_type上)。

作如下的查询

selectdev_no,dev_type

from user_info

whereuser_id =‘U101010’

anddev_type=‘1010’;

二几种主要表连接的比较

类别

嵌套循环连接

排序合并连接

哈希连接

提示

USE_NL

USE_MERGE

USE_HASH

使用的条件

任何连接

主要用于不等价连接,如、>=;

但是不包括<>

·仅用于等价连接

相关资源

CPU、磁盘I/O

内存、临时空间

内存、临时空间

特点

当有高选择性索引或进行限制性搜索时效率比较高,能够快速返回第一次的搜索结果。

当缺乏索引或者索引条件模糊时,排序合并连接比嵌套循环有效。

当缺乏索引或者索引条件模糊时,哈希连接连接比嵌套循环有效。通常比排序合并连接快。

在数据仓库环境下,如果表的纪录数多,效率高。

缺点

当索引丢失或者查询条件限制不够时,效率很低;

当表的纪录数多时,效率低。

所有的表都需要排序。它为最优化的吞吐量而设计,并且在结果没有全部找到前不返回数据。

为建立哈希表,需要大量内存。第一次的结果返回较慢。

三结束语

深入地理解和掌握oracle的表连接对于优化数据库的性能至关重要。由于优化器选择方式的不同,以及统计信息的缺失或统计信息的不准确,ORACLE自动选择的表连接方式不一定是最优的。当SQL语句的执行效率很低时,可通过auto trace对执行计划进行跟踪和分析。当出现多表连接时,需要仔细分析是否有更佳的连接条件。根据系统的特点,必要时可以在SQL中添加HINTS,从而改变SQL的执行计划,从而达到性能优化的目的。

oracle 内部表连接方式,ORACLE 表连接方式相关推荐

  1. Oracle 临时表、数据闪回、查询被锁表、系统常用表、及常用操作

    目录 Oracle 系统常用表/视图 Oracle 临时表概述与创建 flashback  闪回表中被删除的数据 flashback  闪回整个被 drop 的表 查询 Oracle 中被锁定的表 查 ...

  2. oracle 内部表连接方式,oracle表连接方式

    ORACLE表连接方式及常见用法(二) /2010-12-22 13:30:13 /个人分类: 一 引言 数据仓库是目前已知的比较成熟和被广泛采用的解决方案,用于整合电信运营内部所有分散的原始业务数据 ...

  3. oracle 表连接 大表小表_优化必备基础:Oracle中常见的三种表连接方式

    在Oracle SQL语句中,如果from后面有多个表时,表的连接方式是一个很重要的考量. 从Oracle 6开始,优化器就支持下面4种表连接方式: - 嵌套循环连接(Nested Loop Join ...

  4. 深入理解Oracle表(5):三大表连接方式详解之Hash Join的定义,原理,算法,成本,模式和位图

    Hash Join只能用于相等连接,且只能在CBO优化器模式下.相对于nested loop join,hash join更适合处理大型结果集        Hash Join的执行计划第1个是has ...

  5. oracle 非等值关联 优化,Oracle优化器、优化模式、表的连接方式(Hash Join、Nested Loop、Sort Merge Join)...

    查询优化器 Oracle的查询优化器(QO)分为两种: 1. RBO:Ruled-Based Optimization, 基于规则的优化器: 2. CBO :Cost-Based Optimizati ...

  6. oracle 建表id自增长_oracle 左连接、右连接、全外连接、内连接、以及 (+) 号用法...

    Oracle中的连接可分为,内连接(INNER JOIN).外连接(OUTER JOIN).全连接(FULL JOIN),不光是 Oracle,其他很多的数据库也都有这3种连接查询方式. Oracle ...

  7. oracle建表权限问题和JSP连接oracle数据库基本操作

    JSP连接oracle数据库相关操作 1.创建表 打开Enterprise Manager Console,为用户添加权限CREATE ANY TABLE和分配一定的表空间USERS限额1024k. ...

  8. oracle 连接图示,ORACLE 表连接方法

    ORACLE 8i,9i 表连接方法. 一般的相等连接: select * from a, b where a.id = b.id; 这个就属于内连接. 对于外连接: Oracle中可以使用" ...

  9. 318分组聚合,关联查询(多表连接查询)(连接查询),连接查询oracle写法,集合运算ld

    ----------分组聚合:对表里面的数据进行各个维度/角度的统计 -------------统计:需要用 聚合函数 max(目标字段):求最大值 min(目标字段) :求最小值 avg(目标字段) ...

最新文章

  1. 人脸检测--SSH: Single Stage Headless Face Detector
  2. asp.net razor html,从控制台应用程序中的ASP.NET Razor模板生成HTML的当前最佳解决方案是什么?...
  3. 香农编码二叉树c语言,shannon码的编码实验总结.docx
  4. C语言线性表之循环单链表
  5. MSSQL为单独数据库创建登录账户
  6. Atitit.jquery 版本新特性attilax总结
  7. MySql之增删改查总结
  8. mysql中order by的原理
  9. 计算机病毒是不会破坏计算机软件的,计算机病毒是不会破坏计算机硬件的。
  10. 紫鸟超级浏览器-SeleniumAPI通信
  11. 使用两个栈实现一个队列
  12. 网络子系统33_网桥设备的配置更新
  13. 英语魔法师之语法俱乐部 | 笔记2 | 初级句型—简单句 | Chapter1—基本句型及补语
  14. 代码实现数学图形之常用函数,幂,对数,指数,正弦,余弦,正切,余切,反正弦,反余弦,反正切,反余切,双曲正弦,双曲余弦,双曲正切,双曲余切,正割函数,余割函数,双曲正割,双曲正割.
  15. pc计算机shift,电脑上的shift键怎么读?shift表示什么意思?
  16. 最后冲刺—信息系统开发与管理
  17. Unity 进阶 之 实现简单的音频可视化封装(包括音频和麦克风)
  18. Scrapy修改下载图片名字
  19. 关于emgucv的书_EMGUCV基础精编版
  20. 今天架了个奇迹的私服

热门文章

  1. Intel Core Enhanced Core架构/微架构/流水线 (6) - 指令预译码/指令队列/指令译码
  2. java中多线程的创建方式一:
  3. excel引用指定单元格数据_数据、运算符及单元格引用
  4. R plot图片背景设置为透明_学习健明老师发布的R语言练习题的学习笔记(一)...
  5. 基于微型计算机系统的实时时钟设计,基于51单片机的实时时钟设计报告.doc
  6. 【刘文彬】EOS商业落地利器:多签名操作与应用
  7. jison解析Cube信息 存入又读取出来
  8. ubuntu_python_environment
  9. 12.使用default-Action配置统一访问
  10. Unix 网络编程 读书笔记1