我想知道为什么这个查询:
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
执行计划
第二个查询
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
执行计划
在(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)
可能是和索引问题?
您已经发布了可能与实际执行计划不同的解释计划。区别在于解释计划只是优化器(CBO)认为在查询的实际执行期间将遵循的计划,这可能会偏离实际的执行计划。
话虽如此,如果您相信自己的解释计划,那么这绝对是我在评论中假设的优化程序错误。由于某些原因,在您的第一个查询中,CBO使用了错误的快捷方式,并忽略了LEFT OUTER
联接(根本不访问正确的表),并且使用奇怪的NULL is NOT NULL
谓词作为最终过滤器,这总是FALSE
意味着您的最终结果集是永远是空的。
要解决此问题,您可能希望获得Oracle支持并进行数据库修补以修复此错误。
编辑:如果两个表的统计信息都已过期,请收集两个表的统计信息,然后尝试重新运行查询。收集统计数据后,CBO可能会采取正确的计划。但是,统计数据过时仍然不是CBO选择错误执行计划的借口。您可能需要在向Oracle支持小组索取票证之后执行此操作,以便当他们处理该错误行为时仍可再现该错误行为。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句