使用IN或JOIN或EXISTS CLAUSE

时间:2014-10-16 07:25:55

标签: oracle

我有一个使用IN子句编写的查询。我觉得如果有很多记录,性能可能会受到使用IN Clause的影响。

我尝试使用JOIN和EXISTS子句来编写使用IN CLAUSE编写的相同查询。但是,它无法正常工作并根据需要给出结果。

以下是使用IN子句编写的查询片段。

SELECT * FROM TABLE1 WHERE id IN (SELECT id FROM TABLE2 WHERE my_date IN (Select max(my_date) from TABLE2)) ORDER BY id;

我使用EXISTS子句尝试了以下查询,但它无效:

Select * from TABLE1 t1 where exists
(
Select 1 from TABLE2 t2 
where exists 
(
Select max(my_date) from TABLE2 t3
where t2.my_date = t3.my_date)
where t1.id = t2.id) order by t1.id;

有人可以建议如何使用EXISTS和JOINS来实现结果吗?

注意:上例中引用的my_date是DateTime(时间戳)字段。

4 个答案:

答案 0 :(得分:0)

您的IN子句查询非常完美。

 SELECT * FROM TABLE1
  WHERE id IN
   (
    SELECT id FROM TABLE2
    WHERE my_date = (Select max(my_date) from TABLE2)
   ) 
 ORDER BY id;

如果您想要EXISTS

 WITH MY_TABLE2 AS
 (
    SELECT id FROM TABLE2
    WHERE my_date = (Select max(my_date) from TABLE2)
 )
 SELECT * FROM TABLE1 T1
 WHERE EXISTS
 ( 
    SELECT 'X' FROM MY_TABLE2  T2
    WHERE T1.id = T2.id
 )
 ORDER BY id;

如果table1中的每个id在table2中只有一个id,您可以选择JOIN
因为EXISTSIN会压制重复的ID。

 SELECT * FROM TABLE1 T1
 INNER JOIN ( 
               SELECT id FROM TABLE2
               WHERE my_date = (Select max(my_date) from TABLE2)
            ) T2
    ON (T1.id = T2.id)
 ORDER BY id;

答案 1 :(得分:0)

对不起,我无法在mo上测试这个,但是,怎么样:

select * 
  from table1 t1
  where exists (
    select *
      from table2 t2
      where t1.id = t2.id 
        and t2.my_date = (select max(my_date) from table2 t3)
)

另请参阅in和exists之间差异的详细信息(在Oracle中)。你可以从这里开始:Oracle IN vs Exists differences

答案 2 :(得分:0)

感觉会对性能产生影响还是观察对性能产生影响?

任何最新的Oracle优化器应该能够正确处理您的IN查询。检查您的EXPLAIN PLAN并查看是否有任何事情触发了像全表扫描这样的昂贵操作。这是重写查询或者可能在表中添加索引的起点。

答案 3 :(得分:0)

不要重写已经有效的查询,并且表现良好,只是因为你感觉"他们可能会受到影响。测量和测试。

如果您正在运行现代Oracle(10.2或更高版本),那么您应该使用简单的经验法则。

  1. 对待' IN()' vs' EXISTS()'与性能相当,Oracle本身就是
  2. 为场景编写最清晰,最正确的查询
  3. 让您的数据库统计信息保持最新
  4. 分析执行计划
  5. 旧文章,甚至是2003年的问汤姆线程,讨论Oracle 7,8或9,以及IN()如何更慢,或EXISTS()为每个和所有其他基于旧规则的优化器缺点产生的缺点是日期。 Tom Kyte承认了这一点并在稍后写了几篇关于这个主题的文章,但遗憾的是他的旧的Ask Tom档案对IN()的声誉或Oracle的一般能力造成了一些损害。

    IN == EXISTS。 Oracle的优化器将在两者之间进行转换,并在过去五年中测试的大多数场景中选择类似的计划。