oracle是使用函数的表的结果

时间:2013-05-30 22:17:02

标签: sql oracle

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

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

SQL Fiddle

3 个答案:

答案 0 :(得分:2)

我不认为这种方法会更快,事实上我希望它会慢得多。

但是如果你想这样做,你需要将第二个选择中的行放入一个中间集合中,然后使用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;
/

答案 1 :(得分:0)

除了multiset方法,如果你真的想这样做,你也可以把它变为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

答案 2 :(得分: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