2016-11-23 33 views
1
CREATE TABLE ak_temp 
(
    misc_1 varchar2(4000), 
    misc_2 varchar2(4000), 
    time_of_insert timestamp 
); 

查询1(原件):关于Oracle查询功能行为

select * 
    from ak_temp 
where misc_1 in('ankush') 
    or misc_2 in('ankush') 

查询2:

select * 
    from ak_temp 
where 'ankush' in (misc_1,misc_2) 

您好,我有几分相似的问题与疑问,我希望避免查询1,因为我们的生活环境中的成本正在上升,因此我已经用较少的成本计算出了查询2,它们在功能上是否相同?

回答

3

这两者在功能上是等同的,应该产生相同的查询计划,所以不应该有比其他的性能优势(或者任何这样的优势会很小)。 Oracle可能足够聪明,可以利用两个索引,一个索引ak_temp(misc_1),另一个索引ak_temp(misc_2)

但是,您也可以考虑:

select t.* 
from ak_temp t 
where misc_1 = 'ankush' 
union 
select t.* 
from ak_temp t 
where misc_2 = 'ankush'; 

这个版本肯定会采取指标的优势,但如果多行符合两个条件union可以慢下来。

编辑:

为了避免union,你可以这样做:

select t.* 
from ak_temp t 
where misc_1 = 'ankush' 
union all 
select t.* 
from ak_temp t 
where misc_2 = 'ankush' and (misc_1 <> 'ankush' and misc_1 is not null); -- or use `lnnvl()` 
+1

'Union'可避免,并且可以用repaced'UNION ALL'与[LNNVL(HTTPS的帮助: //docs.oracle.com/cd/B19306_01/server.102/b14200/functions078.htm)函数用于查询的底部分支 - 也就是'where misc_2 ='ankush'AND LNNVL(misc_1 ='ankush') '。有关更多详细信息,请参阅此链接:[Oracle - OR扩展](https://blogs.oracle.com/optimizer/entry/或扩展转换)。顺便说一句''union'只能在假设表不包含重复行的情况下工作,否则它不等同于oryginal查询,它会给出错误的结果。 – krokodilko