我有一个使用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(时间戳)字段。
答案 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
,
因为EXISTS
和IN
会压制重复的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或更高版本),那么您应该使用简单的经验法则。
旧文章,甚至是2003年的问汤姆线程,讨论Oracle 7,8或9,以及IN()如何更慢,或EXISTS()为每个和所有其他基于旧规则的优化器缺点产生的缺点是日期。 Tom Kyte承认了这一点并在稍后写了几篇关于这个主题的文章,但遗憾的是他的旧的Ask Tom档案对IN()的声誉或Oracle的一般能力造成了一些损害。
IN == EXISTS。 Oracle的优化器将在两者之间进行转换,并在过去五年中测试的大多数场景中选择类似的计划。