ORACLE 半连接与反连接

概念:所谓半连接,就是在进行连接查询的时候,内层如果有相应的记录及返回一个TRUE,而不需要访问余下的行,如果内层表特别巨大的时候将会大大节省时间。
列子:
 select /* using in */ department_name
      from hr.departments dept
      where department_id in (select department_id from hr.employees emp)
 
============
Plan Table
============
-----------------------------------------------+-----------------------------------+
| Id  | Operation           | Name             | Rows  | Bytes | Cost  | Time      |
-----------------------------------------------+-----------------------------------+
| 0   | SELECT STATEMENT    |                  |       |       |     3 |           |
| 1   |  NESTED LOOPS SEMI  |                  |    10 |   190 |     3 |  00:00:01 |
| 2   |   TABLE ACCESS FULL | DEPARTMENTS      |    27 |   432 |     3 |  00:00:01 |
| 3   |   INDEX RANGE SCAN  | EMP_DEPARTMENT_IX|    41 |   123 |     0 |           |
-----------------------------------------------+-----------------------------------+
使用范围:in和exists操作,实际上很多时候in和exists是等价的,因为他们的执行计划完全一样,所以一般情况下不用去纠结用in还是exists
执行计划:出现SEMI则说明使用了半连接
控制使用半连接:
1、HINT
seminjion -强制使用半连接
no_semijion-不使用半连接
nl_sj-进行嵌套半连接
hash_sj-进行散列半连接
merge_sj-进行排序半连接
使用如下:
 select department_name
      from hr.departments dept
     where department_id in (select /*+ no_semijoin */ department_id from hr.employees emp);
2、系统参数限制
_always_semi_join:默认为choose,允许优化器对所有的半连接方法进行评估并选择它认为最高效的方法。如果指定为hash,
                   merge或者nested_loops就将优化器的选择限定为所指定的连接方式,OFF则禁用了半连接

半连接限制:优化器不会为任何包含在OR分支中的子查询使用半连接,包含DISTINCT关键字可能禁用半连接,如:
select /* using in */ department_name
      from hr.departments dept
      where 1=1 or department_id in (select department_id from hr.employees emp)
半连接条件:
1、语句必须使用in(=any)或exists
2、语句必须在in或exists中有子查询
3、使用exists必须使用关联子查询
4、in或者exists字句不能再OR分支中

另外还有反连接,其原理和半连接一样,在not in 和 not exists中使用,其执行计划中包含ANTI,但是有一点要注意,如果NOT IN 的时候子查询返回有NULL值
则整个查询返回为空。
实际如下:
select department_name
  from hr.departments dept
 where not exists (select 1
          from hr.employees emp
         where emp.department_id = dept.department_id);

select department_name
  from hr.departments dept
 where department_id  not in (select department_id from hr.employees emp where  department_id is not null );
 
是等价的。
执行计划:
--------------------------------------------------------------------------------
| Id  | Operation          | Name              | Rows  | Bytes | Cost (%CPU)| Ti
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                   |    17 |   323 |     3   (0)| 00
|   1 |  NESTED LOOPS ANTI |                   |    17 |   323 |     3   (0)| 00
|   2 |   TABLE ACCESS FULL| DEPARTMENTS       |    27 |   432 |     3   (0)| 00
|*  3 |   INDEX RANGE SCAN | EMP_DEPARTMENT_IX |    41 |   123 |     0   (0)| 00

控制使用反连接:
1、HINT
ANTIJOIN -强制使用反连接
nl_aj-进行嵌套反连接
hash_aj-进行散列反连接
merge_aj-进行排序反连接
注意一下这里没有NO_ANTIJION语法
2、_always_anti_jion
可以这样来取消反连接
alter session set "_always_anti_join"=off;
取值同半连接
反连接条件:
1、语句必须使用NOT IN (!=ALL) 或NOT EXISTS
2、语句必须在NOT IN或NOT EXISTS子句有一个子查询
3、NOT IN或NOT EXISTS子句不能包含在OR分支中
4、NOT EXISTS子句中的子查询必须与外层查询相关
5、注意NOT IN子查询不要返回空值

时间: 2024-09-05 16:16:40

ORACLE 半连接与反连接的相关文章

关于oracle中的反连接

在之前的章节中见到讨论过oracle中的半连接 http://blog.itpub.net/23718752/viewspace-1334483/ 与半连接相对应的是反连接,简而言之半连接就是查询条件中的in,exists,反连接就是not in, not exists这种类型的连接. 在asktom中,tom也对大家关心的in,exists,not in, not exists的问题进行了大量的佐证和解释.因为问题是在2001年左右提出来的,当时还是oracle 8的时代,帖子也沉里许久,在2

MySQL中的反连接(r12笔记第45天)

  关于Oracle的半连接,反连接,我一直认为这是一个能讲很长时间的话题,所以在我的新书<Oracle DBA工作笔记>中讲性能优化的时候,我花了不少的笔墨做了阐述,结果在做MySQL性能优化的时候,优化思路切换到MySQL层面,我发现要说的东西要更多.总体来看,这部分的优化细节MySQL还在路上,不同的版本中都能够一窥其中的变化,可以看到在不断改进.    在表的连接上,半连接,反连接本身很平常,但是统计信息的不够丰富导致执行计划的评估中可能会出现较大差别,会很可能把半连接,反连接的实现方

MySQL反连接的优化总结

今天同事有一个环境发现一条语句执行时间很长,感到非常奇怪.刚好有些时间,就抽空琢磨了下这个问题. 总体来看这个环境还是相对比较繁忙的,线程大概是200多个. # mysqladmin pro|less|wc -l 235 带着好奇查看慢日志,马上定位到这个语句,已做了脱敏处理. # Time: 161013  9:51:45 # User@Host: root[root] @ localhost [] # Thread_id: 24630498  Schema: test Last_errno:

ORACLE 8i的普通连接技术的介绍

oracle ORACLE 8i的普通连接技术的介绍 ==================================== 欢迎大家同我交流:小白  enhydra_boy@tom.com 欢迎转载,请保留本声明,谢谢! ====================================   Oracle 8.1.6 中引入普通连接技术的概念(Generic connectivity),这一连接解决方案满足了对许多异种数据库存储的数据访问需求,同时并不需要安装ORACLE的透明网关(O

利用Oracle自带的连接缓冲类的一个例子

import java.sql.Connection; import oracle.jdbc.pool.OracleConnectionCacheImpl; /** * 连接池管理类 */ public class DBPool { /** 连接池 */ private static OracleConnectionCacheImpl pool = null; /** * 初始化连接池 */ public static void init() { try{ String user = "user

用户如何与Oracle数据库服务器建立连接

用户要想使用Oracle数据库,首先要与数据库建立连接.针对数据库连接,Oracle提供了两种解决方式:专用连接和共享连接. 大部分情况下,我们使用专用连接方式.对专用连接来说,用户在客户端启动了一个应用程序,比如SQL*Plus,于是就在客户端本地启 动了一个用户进程.与Oracle服务器成功建立连接以后,就会在数据库服务器端生成一个对应的服务器进程,该服务器进程作为用户进程 的代理 进程,也叫影子进程,从而代替客户端去执行各种命令并将结果返回.也就是说,用户在客户端输入的各种命令,都是通过位

oracle数据库-oracle 创建shared dblink连接不成功

问题描述 oracle 创建shared dblink连接不成功 oracle 创建shared dblink能创建成功,当是连接不成功.求高手指教

Oracle中SQL语句连接字符串的符号使用介绍_oracle

Oracle中SQL语句连接字符串的符号为|| 复制代码 代码如下: select catstr(tcdm) || (',') from T_YWCJ_RWCJR where cjrjh='009846' and rwid='12050' and jsdm='CJY' 拼接成一条数据并连接一个","

反连接怎么加

问题描述 最近弄的2个网站www.ctwh5.com传统文化网和www.icmyk.net深圳印刷厂一直反连接上不去,谁能教教我怎么搞就好点了 解决方案 解决方案二:都不知道你想干什么--说也说不清楚,谁能帮你?解决方案三:估计是说没有固定IP,用反向代理吧最简单用花生壳