【SQL 学习】表连接--natural join 的一个bug

简介: 自然连接(NATURAL JOIN)是一种特殊的等价连接,它将表中具有相同名称的列自动进行记录匹配。自然连接不必指定任何同等连接条件。这篇文章讲的一个关于natural join 的bug!(由 dingjun123 提示!) SQL> conn store/yang已连接。

自然连接(NATURAL JOIN)是一种特殊的等价连接,它将表中具有相同名称的列自动进行记录匹配。自然连接不必指定任何同等连接条件。这篇文章讲的一个关于natural join 的bug(由 dingjun123 提示!)

SQL> conn store/yang
已连接。
SQL> create table a as select * from all_objects;
表已创建。
SQL> set timing on
SQL> create table b as select * from all_objects;
表已创建。

已用时间:  00: 00: 20.36
SQL> set autot on
SQL> set linesize 100
SQL> select count(*) from a natural join b;
  COUNT(*)                                                                                         
----------                                                                                         
         0         ---错误的结果!                                                                                
已用时间:  00: 00: 00.04

执行计划
----------------------------------------------------------
Plan hash value: 1397777030 
                                                                                                   
------------------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
------------------------------------------------------------------------------------               
|   0 | SELECT STATEMENT    |      |     1 |   316 |       |  1500   (1)| 00:00:18 |
|   1 |  SORT AGGREGATE     |      |     1 |   316 |       |            |          |
|*  2 |   HASH JOIN         |      |     1 |   316 |  8184K|  1500   (1)| 00:00:18 |
|   3 |    TABLE ACCESS FULL| A    | 49280 |  7603K|       |   281   (1)| 00:00:04 |
|   4 |    TABLE ACCESS FULL| B    | 66983 |    10M|       |   282   (1)| 00:00:04 |
------------------------------------------------------------------------------------
                                                                                                   
Predicate Information (identified by operation id):                                                
---------------------------------------------------                                                
                                                                                                   
   2 - access("A"."EDITION_NAME"="B"."EDITION_NAME" AND                                            
              "A"."NAMESPACE"="B"."NAMESPACE" AND "A"."SECONDARY"="B"."SECONDARY" AND
              "A"."GENERATED"="B"."GENERATED" AND "A"."TEMPORARY"="B"."TEMPORARY" AND
              "A"."STATUS"="B"."STATUS" AND "A"."TIMESTAMP"="B"."TIMESTAMP" AND
              "A"."LAST_DDL_TIME"="B"."LAST_DDL_TIME" AND "A"."CREATED"="B"."CREATED" AND
              "A"."OBJECT_TYPE"="B"."OBJECT_TYPE" AND
              "A"."DATA_OBJECT_ID"="B"."DATA_OBJECT_ID" AND
              "A"."OBJECT_ID"="B"."OBJECT_ID" AND "A"."SUBOBJECT_NAME"="B"."SUBOBJECT_NAME
              " AND "A"."OBJECT_NAME"="B"."OBJECT_NAME" AND "A"."OWNER"="B"."OWNER")
                                                                                                   
Note      
-----
   - dynamic sampling used for this statement                                                      

统计信息
------------------------------------------------------
       1801  recursive calls
          0  db block gets
       1407  consistent gets
          0  physical reads
          0  redo size
        418  bytes sent via SQL*Net to client
        416  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
         17  sorts (memory)    
          0  sorts (disk)   
          1  rows processed

SQL> set autot off
SQL> truncate table a;
表被截断。
已用时间:  00: 00: 00.43
SQL> truncate table b;
表被截断。
已用时间:  00: 00: 00.04
SQL> drop table a;
表已删除。
已用时间:  00: 00: 00.57
SQL> drop table b;
表已删除。
已用时间:  00: 00: 00.06
SQL> create table a (id number ,name varchar2(10)) ;
表已创建。
已用时间:  00: 00: 00.10
SQL> insert into a values (1,'aa');
已创建 1 行。
已用时间:  00: 00: 00.00
SQL> insert into a values (2,'bb');
已创建 1 行。
已用时间:  00: 00: 00.00
SQL> create table b as select * from a ;
表已创建。
已用时间:  00: 00: 00.29
SQL> set autot on
SQL> select count(*) from a natural join b;

  COUNT(*)                                                                                         
----------                                                                                         
         2      ----结果是正确的 

 已用时间:  00: 00: 00.03

执行计划
----------------------------------------------------------                                         
Plan hash value: 1397777030                                                                        
                                                                                                   
----------------------------------------------------------------------------                       
| Id  | Operation           | Name | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------                       
|   0 | SELECT STATEMENT    |      |     1 |    40 |     7  (15)| 00:00:01 |
|   1 |  SORT AGGREGATE     |      |     1 |    40 |            |          |
|*  2 |   HASH JOIN         |      |     1 |    40 |     7  (15)| 00:00:01 |
|   3 |    TABLE ACCESS FULL| A    |     2 |    40 |     3   (0)| 00:00:01 |
|   4 |    TABLE ACCESS FULL| B    |     2 |    40 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------                       
Predicate Information (identified by operation id):
--------------------------------------------------
                                                                                                   
   2 - access("A"."NAME"="B"."NAME" AND "A"."ID"="B"."ID")
                                                                                                   
Note                         
-----            
   - dynamic sampling used for this statement

统计信息
----------------------------------------------------------
        103  recursive calls
          0  db block gets
         34  consistent gets
          5  physical reads
          0  redo size 
        419  bytes sent via SQL*Net to client
        416  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          4  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL> truncate table a;
表被截断。
已用时间:  00: 00: 00.25
SQL> truncate table b;
表被截断。
已用时间:  00: 00: 00.01
SQL> drop table a;
表已删除。
已用时间:  00: 00: 00.28
SQL> drop table b;
表已删除。
已用时间:  00: 00: 00.06

SQL> create table b as select * from all_objects where rownum 表已创建。
已用时间:  00: 00: 00.87
SQL> drop table a;
表已删除。
已用时间:  00: 00: 00.35
SQL> create table a  as select * from b; a和b 两个表是一样的。
表已创建。
已用时间:  00: 00: 00.25
SQL> select * from a
  2  minus
  3  select * from b;
未选定行
已用时间:  00: 00: 00.03

SQL> select count(*) from a;
  COUNT(*)                                                                                         
----------                                                                                         
       999                                                                                         
已用时间:  00: 00: 00.01
SQL> select count(*) from b;

  COUNT(*)                                                                                         
----------                                                                                         
       999                                                                                         
已用时间:  00: 00: 00.01

SQL> set autot on
SQL> select count(*) from a natural join b;

  COUNT(*)                                                                                         
----------                                                                                         
         0   ---应该返回999行,但是结果是0 显然这是一个bug                                                                                      
已用时间:  00: 00: 00.01
执行计划
----------------------------------------------------------
Plan hash value: 1397777030                                                                        
                                                                                                   
----------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |     1 |   316 |    13   (8)| 00:00:01 |
|   1 |  SORT AGGREGATE     |      |     1 |   316 |            |          |
|*  2 |   HASH JOIN         |      |     1 |   316 |    13   (8)| 00:00:01 |
|   3 |    TABLE ACCESS FULL| A    |   999 |   154K|     6   (0)| 00:00:01 |
|   4 |    TABLE ACCESS FULL| B    |   999 |   154K|     6   (0)| 00:00:01 |
----------------------------------------------------------------------------
                                                                                                   
Predicate Information (identified by operation id):
---------------------------------------------------
                                                                                                   
   2 - access("A"."EDITION_NAME"="B"."EDITION_NAME" AND
              "A"."NAMESPACE"="B"."NAMESPACE" AND "A"."SECONDARY"="B"."SECONDARY" AND
              "A"."GENERATED"="B"."GENERATED" AND "A"."TEMPORARY"="B"."TEMPORARY" AND
              "A"."STATUS"="B"."STATUS" AND "A"."TIMESTAMP"="B"."TIMESTAMP" AND
              "A"."LAST_DDL_TIME"="B"."LAST_DDL_TIME" AND "A"."CREATED"="B"."CREATED"
              AND "A"."OBJECT_TYPE"="B"."OBJECT_TYPE" AND
              "A"."DATA_OBJECT_ID"="B"."DATA_OBJECT_ID" AND
              "A"."OBJECT_ID"="B"."OBJECT_ID" AND 
              "A"."SUBOBJECT_NAME"="B"."SUBOBJECT_NAME" AND
              "A"."OBJECT_NAME"="B"."OBJECT_NAME" AND "A"."OWNER"="B"."OWNER")
Note                                                                                               
-----     
   - dynamic sampling used for this statement

统计信息
----------------------------------------------------------
        582  recursive calls
          0  db block gets
        168  consistent gets
          0  physical reads
          0  redo size
        418  bytes sent via SQL*Net to client
        416  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          6  sorts (memory)       
          0  sorts (disk)
          1  rows processed
SQL> conn scott/yang
已连接。
SQL> select ename ,dname from emp natural join dept;
ENAME      DNAME     
---------- -----------
CLARK      ACCOUNTING
KING       ACCOUNTING
MILLER     ACCOUNTING
JONES      RESEARCH
FORD       RESEARCH
ADAMS      RESEARCH
SMITH      RESEARCH                                                                                
SCOTT      RESEARCH
WARD       SALES
TURNER     SALES
ALLEN      SALES
JAMES      SALES
BLAKE      SALES
MARTIN     SALES
-------结果是正确的!

已选择14行。
执行计划
----------------------------------------------------------                                         
Plan hash value: 844388907                                                                         
                                                                                                   
----------------------------------------------------------------------------------------
| Id  | Operation                    | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------           
|   0 | SELECT STATEMENT             |         |    14 |   308 |     6  (17)| 00:00:01 |
|   1 |  MERGE JOIN                  |         |    14 |   308 |     6  (17)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| DEPT    |     4 |    52 |     2   (0)| 00:00:01 |
|   3 |    INDEX FULL SCAN           | PK_DEPT |     4 |       |     1   (0)| 00:00:01 |
|*  4 |   SORT JOIN                  |         |    14 |   126 |     4  (25)| 00:00:01 |
|   5 |    TABLE ACCESS FULL         | EMP     |    14 |   126 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------------------           
                                                                                                   
Predicate Information (identified by operation id):  
---------------------------------------------------
                                                                                                   
   4 - access("EMP"."DEPTNO"="DEPT"."DEPTNO")
       filter("EMP"."DEPTNO"="DEPT"."DEPTNO")
统计信息
---------------------------------------------------
          0  recursive calls
          0  db block gets
         11  consistent gets
          0  physical reads 
          0  redo size  
        674  bytes sent via SQL*Net to client
        416  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client                                                     
          1  sorts (memory)
          0  sorts (disk)
         14  rows processed
---贴出执行计划,只是想看看 natural join 会走什么样的计划。
重点是这个对于all_objects 构造出的表使用natural join 查询时 没有给出正确的结果。。

目录
相关文章
|
3天前
|
SQL
SQL JOIN
【11月更文挑战第06天】
16 4
|
9天前
|
SQL 关系型数据库 MySQL
图解 SQL 里的各种 JOIN
用文氏图表示 SQL 里的各种 JOIN,一下子就理解了。
23 2
|
5月前
|
SQL 关系型数据库 MySQL
SQL FULL OUTER JOIN 关键字
SQL FULL OUTER JOIN 关键字
49 2
|
28天前
|
SQL 分布式计算 Java
Hadoop-11-MapReduce JOIN 操作的Java实现 Driver Mapper Reducer具体实现逻辑 模拟SQL进行联表操作
Hadoop-11-MapReduce JOIN 操作的Java实现 Driver Mapper Reducer具体实现逻辑 模拟SQL进行联表操作
31 3
|
3月前
|
Java 网络架构 数据格式
Struts 2 携手 RESTful:颠覆传统,重塑Web服务新纪元的史诗级组合!
【8月更文挑战第31天】《Struts 2 与 RESTful 设计:构建现代 Web 服务》介绍如何结合 Struts 2 框架与 RESTful 设计理念,构建高效、可扩展的 Web 服务。Struts 2 的 REST 插件提供简洁的 API 和约定,使开发者能快速创建符合 REST 规范的服务接口。通过在 `struts.xml` 中配置 `<rest>` 命名空间并使用注解如 `@Action`、`@GET` 等,可轻松定义服务路径及 HTTP 方法。
56 0
|
3月前
|
SQL 存储 数据挖掘
"SQL JOIN大揭秘:解锁多表联合查询的终极奥义,从内到外,左至右,全连接让你数据世界畅通无阻!"
【8月更文挑战第31天】在数据库领域,数据常分散在多个表中,而SQL JOIN操作如同桥梁,连接这些孤岛,使数据自由流动,编织成复杂的信息网络。本文通过对比内连接、左连接、右连接和全连接的不同类型,并结合示例代码,展示SQL JOIN的强大功能。掌握JOIN技术不仅能高效查询数据,更是数据分析和数据库管理的关键技能。
86 0
|
4月前
|
JSON 数据格式 SQL
SQL开发问题之直接使用join方法在处理字符串类型属性时可能会遇到性能问题如何解决
SQL开发问题之直接使用join方法在处理字符串类型属性时可能会遇到性能问题如何解决
|
4月前
|
SQL
SQL FULL OUTER JOIN 关键字
【7月更文挑战第17天】SQL FULL OUTER JOIN 关键字。
38 6
|
4月前
|
SQL
SQL INNER JOIN 关键字
【7月更文挑战第17天】SQL INNER JOIN 关键字。
42 5
|
4月前
|
SQL 数据库
SQL LEFT JOIN 关键字
【7月更文挑战第17天】SQL LEFT JOIN 关键字。
33 4