ORACLE左外连接问题(空表?)

时间:2014-10-08 16:50:47

标签: sql oracle

我想知道为什么这个查询:

select l.objectID LEFT_CODE, r.object_code RIGHT_CODE
from OGGETTO_ORGANIZZATIVO l left outer join
    ANAG_OGGETTO_ORGANIZZATIVO r on l.objectID = r.objectID
WHERE r.objectID IS NULL;

返回一些行,而另一个查询

select l.objectID LEFT_CODE
from OGGETTO_ORGANIZZATIVO l left outer join
    ANAG_OGGETTO_ORGANIZZATIVO r on l.objectID = r.objectID
WHERE r.objectID IS NULL;

不会返回任何内容。 我的问题是在右表中插入左表中但不在右表中的所有行;目前正确的桌子是空的。

似乎如果我没有在select子句中引用正确的字段,oracle将不会管理外连接。

提前致谢。 保罗

[UPDATE] 首次查询

select l.codice_oggetto_SAP
from oggetto_organizzativo l left outer join
  ANAG_OGGETTO_ORGANIZZATIVO_SAP r
    ON l.codice_oggetto_sap = r.codice_oggetto_SAP
WHERE r.codice_oggetto_sap is null

执行计划 enter image description here

第二次查询

select l.codice_oggetto_SAP, r.codice_oggetto_SAP
from oggetto_organizzativo l left outer join
  ANAG_OGGETTO_ORGANIZZATIVO_SAP r
    ON l.codice_oggetto_sap = r.codice_oggetto_SAP
WHERE r.codice_oggetto_sap is null

执行计划 enter image description here

第一个执行计划声明(NULL IS NOT NULL)在我看来好奇......

[第二次更新] @toddlermenot,

但是为什么这个工作???:

CREATE TABLE LEFT_TBL
   (    "OBJECTID" VARCHAR2(20 BYTE)  ) ;

CREATE TABLE RIGHT_TBL
   (    "OBJECTID" VARCHAR2(20 BYTE)  ) ;

INSERT ALL
  INTO LEFT_TBL (OBJECTID) VALUES ('AAA')
  INTO LEFT_TBL (OBJECTID) VALUES ('BBB')
  INTO LEFT_TBL (OBJECTID) VALUES ('CCC')  
SELECT * from DUAL;

SELECT l.objectID
FROM LEFT_TBL l LEFT OUTER JOIN RIGHT_TBL r
  ON L.OBJECTID = r.OBJECTID
WHERE r.OBJECTID IS NULL;

有了这个执行计划

Plan hash value: 2059691840

--------------------------------------------------------------------------------
| Id  | Operation          | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |           |     3 |    72 |     5   (0)| 00:00:01 |
|*  1 |  HASH JOIN ANTI    |           |     3 |    72 |     5   (0)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| LEFT_TBL  |     3 |    36 |     3   (0)| 00:00:01 |
|   3 |   TABLE ACCESS FULL| RIGHT_TBL |     1 |    12 |     2   (0)| 00:00:01 |
--------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("L"."OBJECTID"="R"."OBJECTID")

Note
-----
   - dynamic sampling used for this statement (level=2)

可能和索引有问题吗?

2 个答案:

答案 0 :(得分:0)

您已发布解释计划,这可能与实际的执行计划不同。 差异是解释计划正是优化程序(CBO)认为它将在查询的实际执行期间遵循哪些可能偏离真正的执行计划

话虽如此,如果你的解释计划被认为是,那么这肯定是一个优化器错误,正如我在评论中假设的那样。 出于某种原因,在您的第一个查询中,CBO正在使用不正确的快捷方式并忽略LEFT OUTER连接(根本不访问右表)并使用奇怪的NULL is NOT NULL谓词作为最终的过滤器总是FALSE意味着你的最终结果集总是空的。

要解决此问题,您可能希望使用Oracle支持提高票证并修补数据库以修复此错误。

编辑:如果两个表的统计信息都已过期,请在两个表上收集统计信息并尝试重新运行查询。收集统计数据后,CBO可能会采取正确的计划。然而,过时的统计数据仍然不是CBO选择错误执行计划的借口。在将票证提交到Oracle Support之后,您可能希望这样做,以便在处理它时,这种不正确的行为仍然可以重现。

答案 1 :(得分:0)

错误10269193-外部联接和CASE表达式优化(不必显示CASE)或LIKE运算符(文档ID 10269193.8)的结果错误

产品(组件)

Oracle服务器(Rdbms)

相信受影响的版本范围

版本> = 11.2但低于12.1

症状:

相关:

  • 可能会发生内部错误(ORA-600)
  • 错误的结果
  • ORA-600 [kkfdjoi:kkfdnpart_DIM1]