2013-05-30 24 views
0

我正在做一些测试,看看我是否可以加快特定的结果集,但似乎无法得到这个特定的解决方案工作。我有数据来自几个不同的表格,并希望将这些数据结合起来。我想在不使用联合选择的情况下尝试一下,看看我是否获得了性能改进。从表使用函数的oracle结果

当我在一个函数中有一个自定义表/对象类型时,它似乎在执行后续选择时从表中删除现有数据。是否有办法在未删除先前数据的情况下执行后续选择?

SQL Fiddle

+2

你仍然在做两个选择,加上一个上下文切换到PL/SQL,所以不知道为什么你期望它更快。唯一显着的区别是你避免了排序来删除重复项 - 你也可以通过使用union all来避免重复项。 –

回答

2

我不认为这种做法会更快,其实我希望它是慢得多。

但是,如果您确实想要这样做,则需要将第二个select中的行放入中间集合中,然后使用multiset union加入。

事情是这样的:

create or replace function 
    academic_history(p_student_id number) 
    return ah_tab_type 
    is 
    result ah_tab_type; 
    t ah_tab_type; 
begin 

    select ah_obj_type(student_id,course_code,grade) 
    bulk collect into result 
    from completed_courses 
    where student_id = p_student_id; 

    select ah_obj_type(student_id,course_code,'P') 
    bulk collect into T 
    from trans_courses 
    where student_id = p_student_id; 

    result := result multiset union t; 

    return result; 
end; 
/
0

还有多集的方法,如果你真的想这样做,你也可以让它pipelined function

create or replace function 
academic_history(p_student_id number) 
return ah_tab_type pipelined 
is 
    T ah_tab_type; 
begin 
    select ah_obj_type(student_id,course_code,grade) 
    bulk collect 
    into T 
    from completed_courses 
    where student_id = p_student_id; 

    for i in 1..T.count loop 
     pipe row (T(i)); 
    end loop; 

    select ah_obj_type(student_id,course_code,'P') 
    bulk collect 
    into T 
    from trans_courses 
    where student_id = p_student_id; 

    for i in 1..T.count loop 
     pipe row (T(i)); 
    end loop; 

    return; 
end; 

SQL Fiddle

+0

我看过流水线功能。我认为我的返回数据集30-50行将足够小,不需要它。但是这仍然是非常丰富的。谢谢。 – Gordolio

0

谢谢a_horse_with_no_name指出做多次选择一次一个可能会更慢。我能够通过过滤每个选择的student_id来缩短执行时间,然后合并(而不是将所有内容合并,然后过滤)。在数据集,我这个解决方案的工作是最快的只需要不到1/10秒......

create or replace function 
    academic_history(p_student_id number) 
    return ah_tab_type 
    is 
    T ah_tab_type; 
begin 

    select ah_obj_type(student_id,course_code,grade) 
    bulk collect 
    into T 
    from (
    select student_id,course_code,grade 
    from completed_courses 
    where student_id = p_student_id 
    union 
    select student_id,course_code,'P' 
    from trans_courses 
    where student_id = p_student_id); 

    return T; 
end; 
/
select * 
from table(academic_history(1)); 

,这花了2-3秒执行...

create view vw_academic_history 
select student_id,course_code,grade 
from completed_courses 
union 
select student_id,course_code,'P' 
from trans_courses; 

select * 
from vw_academic_history 
where student_id = 1; 

SQLFiddle