首页 > 数据库 >Oracle外连接等价于内连接的情况

Oracle外连接等价于内连接的情况

时间:2023-06-15 18:11:50浏览次数:46  
标签:00 tt 51 等价 COL col Oracle 00.01 连接

 

Oracle外连接等价于内连接的情况

 

实际之前有过研究,Oracle外连接的执行计划中没有出现OUTER的例子,现在展开来讲。

以左连接为例子,有SQL如下:

左边的执行计划中id=2并带有OUTER,表示不是外连接。

右边的执行计划和左边的执行计划一模一样,证明左边的SQL完全等价与右边的SQL。

select count(*) from t left join tt on t.col = tt.col where tt.col='b';                                              select count(*) from t,tt where t.col = tt.col and tt.col='b';
Plan hash value: 3743140366                                                                                          Plan hash value: 3743140366
                                                                                                                     
-----------------------------------------------------------------------------------------------------------------    -----------------------------------------------------------------------------------------------------------------
| Id  | Operation           | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |    | Id  | Operation           | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------    -----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |      1 |        |      1 |00:00:00.01 |      51 |       |       |          |    |   0 | SELECT STATEMENT    |      |      1 |        |      1 |00:00:00.01 |      51 |       |       |          |
|   1 |  SORT AGGREGATE     |      |      1 |      1 |      1 |00:00:00.01 |      51 |       |       |          |    |   1 |  SORT AGGREGATE     |      |      1 |      1 |      1 |00:00:00.01 |      51 |       |       |          |
|*  2 |   HASH JOIN         |      |      1 |      1 |      1 |00:00:00.01 |      51 |  2616K|  2616K|  793K (0)|    |*  2 |   HASH JOIN         |      |      1 |      1 |      1 |00:00:00.01 |      51 |  2616K|  2616K|  794K (0)|
|*  3 |    TABLE ACCESS FULL| T    |      1 |      1 |      1 |00:00:00.01 |      45 |       |       |          |    |*  3 |    TABLE ACCESS FULL| T    |      1 |      1 |      1 |00:00:00.01 |      45 |       |       |          |
|*  4 |    TABLE ACCESS FULL| TT   |      1 |      1 |      1 |00:00:00.01 |       6 |       |       |          |    |*  4 |    TABLE ACCESS FULL| TT   |      1 |      1 |      1 |00:00:00.01 |       6 |       |       |          |
-----------------------------------------------------------------------------------------------------------------    -----------------------------------------------------------------------------------------------------------------
                                                                                                                     
Predicate Information (identified by operation id):                                                                  Predicate Information (identified by operation id):
---------------------------------------------------                                                                  ---------------------------------------------------
                                                                                                                     
   2 - access("T"."COL"="TT"."COL")                                                                                     2 - access("T"."COL"="TT"."COL")
   3 - filter("T"."COL"='b')                                                                                            3 - filter("T"."COL"='b')
   4 - filter("TT"."COL"='b')                                                                                           4 - filter("TT"."COL"='b')

 

Oracle外连接可以等价改写为内连接的前提条件,当被驱动表的字段出现在where中并且不能为is null(如果是连接列is null是另外一种情况:反连接)。

原因是驱动表进行谓词条件过滤后的全部是数据都会出现在最终结果集中,不满足连接条件的时候被驱动表的字段均为null,这个时候被驱动表的字段出现在where(如上边的tt.col='b')表示这一部分数据肯定是满足连接条件的,那么自然可以改写为内连接。

 

不能改写的例子防偷

select count(*) from t left join tt on t.col = tt.col where tt.name is null;                                            select count(*) from t left join tt on t.col = tt.col where tt.col is null;
Plan hash value: 2949581252                                                                                             Plan hash value: 3556837987
                                                                                                                        
---------------------------------------------------------------------------------------------------------------------   -------------------------------------------------------------------------------------------------------------------
| Id  | Operation               | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |   | Id  | Operation             | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
---------------------------------------------------------------------------------------------------------------------   -------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |      |      1 |        |      1 |00:00:00.02 |      51 |       |       |          |   |   0 | SELECT STATEMENT      |      |      1 |        |      1 |00:00:00.01 |      51 |       |       |          |
|   1 |  SORT AGGREGATE         |      |      1 |      1 |      1 |00:00:00.02 |      51 |       |       |          |   |   1 |  SORT AGGREGATE       |      |      1 |      1 |      1 |00:00:00.01 |      51 |       |       |          |
|*  2 |   FILTER                |      |      1 |        |      1 |00:00:00.02 |      51 |       |       |          |   |*  2 |   HASH JOIN RIGHT ANTI|      |      1 |   1000K|      1 |00:00:00.01 |      51 |  2616K|  2616K|  897K (0)|
|*  3 |    HASH JOIN RIGHT OUTER|      |      1 |   1000K|  24578 |00:00:00.02 |      51 |  2061K|  2061K|  833K (0)|   |   3 |    TABLE ACCESS FULL  | TT   |      1 |   1000K|      2 |00:00:00.01 |       6 |       |       |          |
|*  4 |     TABLE ACCESS FULL   | TT   |      1 |      1 |      2 |00:00:00.01 |       6 |       |       |          |   |   4 |    TABLE ACCESS FULL  | T    |      1 |   1000K|  24578 |00:00:00.01 |      45 |       |       |          |
|   5 |     TABLE ACCESS FULL   | T    |      1 |   1000K|  24578 |00:00:00.01 |      45 |       |       |          |   -------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------   
                                                                                                                        Predicate Information (identified by operation id):
Predicate Information (identified by operation id):                                                                     ---------------------------------------------------
---------------------------------------------------                                                                     
                                                                                                                           2 - access("T"."COL"="TT"."COL")
   2 - filter("TT"."NAME" IS NULL)
   3 - access("T"."COL"="TT"."COL")
   4 - filter("TT"."COL" IS NOT NULL)

 

标签:00,tt,51,等价,COL,col,Oracle,00.01,连接
From: https://www.cnblogs.com/PiscesCanon/p/17483709.html

相关文章

  • 利用VMware安装centos7+docker部署Oracle数据库
    由于本机资源有限,docke容器能够利用最小资源实现目前需求准备:VMware、centos镜像文件VMware安装centos后,设置网络桥接模式,联通外网,为安装docker准备执行:首先,将docker部署再虚拟机内,(新机器直接安装,若安装过旧版本需要卸载,请参考https://www.runoob.com/docker/centos-docker-i......
  • oracledb处理游标中的对象类型数据
    如果Oracle定义了以下对象类型1CREATEORREPLACETYPE"TY_RESULT"2ASOBJECT3(4itemCHAR(8),5cntNUMBER(20),67--构造空对象8CONSTRUCTORFUNCTIONTY_RESULTRETURNSELFASRESULT,9);并用于存储过程的返回,放在refcursor中 用以......
  • BLE中GAP层中广播、扫描、连接等概念在LL层的具体实现
    BLE中GAP层中广播、扫描、连接等概念在LL层的具体实现在spec中GAP的章节里对广播、扫描、连接的概念进行了说明。但缺乏具体实现的解释。Vol3:CoreSystemPackage[Hostvolume]PartC:GenericAccessProfile而在LL层章节中则提供了相关GAP相关数据包交互的流程。Vol......
  • Windows Server 2022 安装配置 MYSQL 及远程连接
    官方下载地址:https://dev.mysql.com/downloads/mysql/解压后新建my.ini放在解压目录下。配置环境变量:此电脑->属性->高级系统设置->环境变量->系统变量。找到path,新建D:\ProgramFiles\mysql-8.0.33-winx64\bin[mysqld]#设置3306端口port=3306#设置mysql的安装目录based......
  • oracle常用函数(持续更新)
    1.table()把返回结果集合的函数返回的结果,以表的形式返回例:table(p_split('1,2,3'),',')2.to_char()按照指定格式输出字符串to_char(sysdate,'YYYYMMDD')//fm除去空格和0//9999999.0099:允许小数点左边最大正数为7位,小数点右边最少2位,最多4位,且在第5位进行四舍五入......
  • 外连接消除技术应用
    上回介绍了外连接消除技术。今天更进一步来聊聊这个话题。select*fromarightjoinbona.m1=b.m1leftjoinconc.c1=b.c1wherec.c1in(1,2,3);基于外连接消除技术,这个语句leftjoin可以改写成innerjoin:select*fromarightjoinbona.m1=b.m1......
  • 【SQL 优化器技术系列】 外连接消除
    Oracle2005年出了一个30多页的小册子,《QueryOptimizationinOracleDatabase10gRelease2》,介绍了常见的优化器技术。我是做SQL执行的,优化部分只了解皮毛,从没有系统学习过。本系列逐个学习和介绍,自我提升,也帮助他人。外连接消除就是将一个outerjoin转换成innerjoin。......
  • 数据库连接池-Druid的使用
       packagedruid;/**druid数据连接池**/importcom.alibaba.druid.pool.DruidDataSourceFactory;importjavax.sql.DataSource;importjava.io.FileInputStream;importjava.io.FileReader;importjava.sql.Connection;importjava.util.Properties;p......
  • plsq怎么查看oracle最近执行的sql语句
    plsq怎么查看oracle最近执行的sql语句?怎么可以使用如下语句查询 //其中sql_text即为执行的sql语句,sql_exec_start为sql执行开始时间SELECTa.sql_text,a.sql_exec_start,a.*FROMV$SQL_MONITORawherea.service_name='easorcl'ORDERBYSQL_EXEC_STARTDESC;......
  • Oracle-任务调度(DBMS_Scheduler)
    Dbms_SchedulerOracle10g之前,可以使用dbms_job来管理定时任务:dbms_job.submit(job=>outjob,what=>'pro_name;',next_date=>sysdate,inteval=>'sysdate+1/24');10g之后,Oracle引入了dbms_scheduler和program,在功能方面,它比dbms_job提供了更强大的功能和灵活的机制/管理......