0

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

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

SQL小提琴

4

3 回答 3

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;
/
于 2013-05-30T22:39:50.517 回答
0

除了多集方法之外,如果您真的想这样做,您还可以将其设为流水线函数

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 小提琴

于 2013-05-30T22:55:57.890 回答
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

于 2013-05-31T16:50:53.473 回答