Oracle Optimizer意外结果

时间:2012-05-21 13:40:44

标签: oracle

我有一个编写以下查询的同事。第一个工作,第二个工作不工作。此外,如果从子查询中删除聚合函数,它也可以。 oracle优化器正在做一些奇怪的事情。有什么想法吗?在SQL Developer 3.1中运行,针对11.1.0.6.0 64位。

这有效:

SELECT
  a.fd_customer_key
, b.fd_customer_key
, b.counter
FROM FETCH_CUSTOMER a
, (select fd_customer_key, count(*) as counter from fetch_customer_order group by fd_customer_key) b
where a.fd_customer_key = b.fd_customer_key (+)
and b.counter is null

这不是:

SELECT
a.fd_customer_key
, b.fd_customer_key
, b.counter
FROM FETCH_CUSTOMER a
, (select fd_customer_key, count(*) as counter from fetch_customer_order group by fd_customer_key) b
 where a.fd_customer_key = b.fd_customer_key (+)
 and b.fd_customer_key is null

2 个答案:

答案 0 :(得分:2)

实际上是的,你提供的两个查询都应该以同样的方式破解,但是如果我理解你的需要,你是否试图选择没有秩序的fd_customer_key?

我建议您根据自己的需要进行以下查询,更简单,更省力:

SELECT a.fd_customer_key
  FROM FETCH_CUSTOMER a
 WHERE NOT EXISTS (SELECT 1
          FROM fetch_customer_order b
         WHERE a.fd_customer_key = b.fd_customer_key)

答案 1 :(得分:0)

您似乎正在尝试进行反连接(找到FETCH_CUSTOMERFETCH_CUSTOMER_ORDER中没有相应行的行。

使用Oracle,您不必使用这个聪明的OUTER JOIN技巧来编写反连接,您可以使用NOT INNOT EXISTS运算符,让优化程序找到最佳计划。这将同样有效且易于阅读。

无论如何,我无法重现你的发现,这是我的设置:

CREATE TABLE a (ID NUMBER PRIMARY KEY);
CREATE TABLE b (a_id NUMBER NOT NULL, DATA VARCHAR2(30));
INSERT INTO a (SELECT object_id FROM all_objects);
INSERT INTO b (SELECT object_id, object_name 
                 FROM all_objects WHERE object_type = 'VIEW');

SELECT a.id, b.a_id, b.cnt
  FROM a, (SELECT a_id, COUNT(*) cnt FROM b GROUP BY a_id) b
 WHERE a.id = b.a_id (+)
   AND b.cnt IS NULL;

SELECT a.id, b.a_id, b.cnt
  FROM a, (SELECT a_id, COUNT(*) cnt FROM b GROUP BY a_id) b
 WHERE a.id = b.a_id (+)
   AND b.a_id IS NULL;

您会发现两个查询都返回行。你的数据库版本是什么?