如何在条件优化的情况下优化Oracle的代码?

时间:2016-09-01 16:43:52

标签: sql oracle oracle11g

我的SQL根据相同的条件有两个结果字段。现在我必须写两次。我想知道数据库编译器是否已经自动优化了代码,或者我是否必须改变其他方式来优化SQL?

select id,parent_id as p_Id,name,
(case when exists(select * from t_group t2 where t1.id=t2.parent_id) 
then 2 else 1 end) type,
(case when exists(select * from t_group t2 where t1.id=t2.parent_id) 
then 'true' else 'false' end) as is_Parent
from t_group t1

我试图像这样改变它,但失败了。

select id,parent_id as p_Id,name,
(case when exists(select * from t_group t2 where t1.id=t2.parent_id) 
then 2 else 1 end) type,
(case when type==1 
then 'true' else 'false' end) as is_Parent
from t_group t1

3 个答案:

答案 0 :(得分:1)

使用公用表表达式或内联视图获取表达式一次,然后在该CTE或内联视图之外使用它。这就是我的意思,使用内联视图:

SELECT v.id, v.parent_id, v.name, v.type, case when v.type = 1 THEN 'TRUE' ELSE 'FALSE' END is_parent 
FROM 
(
select id,parent_id as p_Id,name,
(case when exists(select * from t_group t2 where t1.id=t2.parent_id) 
then 2 else 1 end) type
from t_group t1
) v

答案 1 :(得分:0)

我会使用左连接重写它以避免每行执行多个查询,同时确保左连接派生表永远不会返回多行:

select t.id, 
       t.parent_id as p_id,
       t.name,
       case when c.parent_id is not null then 2 else 1 end as type,
       case when c.parent_id is not null then 'true' else 'false' end as is_parent
  from t_group t
  left join (select parent_id,
                    row_number() over (partition by parent_id order by null) as rn
               from t_group) c
    on c.parent_id = t.id
   and c.rn = 1

答案 2 :(得分:0)

select id,parent_id as p_Id,name,
       decode(t2.parent_id,NULL,1,2) type,
       decode(t2.parent_id,NULL,'false','true') is_Parent
  from t_group t1
  left join(select distinct parent_id from t_group) t2
    on t1.id=t2.parent_id

如果列parent_id上存在索引,则优化器会发出'索引范围扫描' (与选择中的子查询一样)或'索引快速全扫描' (如果理解它更快)。