我有一个非常有效的光标,但是当我打开它时,有一百万次,我希望它也能以缓慢的方式对行进行排序。
显而易见的解决方案是拥有光标的第二个副本,一个按顺序,另一个没有。
然而,这很乏味,将来容易出错。
问题是:是否有可能使用游标参数强制oracle跳过整个order by子句(当然没有动态sql)?
我想要实现的示例代码:
declare
cursor c_cur(skip_order varchar2) is
select /*+ gather_plan_statistics */ xes.x
from ( select 1 x from dual union all
select 3 x from dual union all
select 2 x from dual
) xes
order by case when skip_order = 'Y' then null else xes.x end
;
type t_x is table of c_cur%rowtype;
tab_xes t_x;
begin
open c_cur('Y'); -- and sometimes 'N' ...
fetch c_cur bulk collect into tab_xes;
close c_cur;
for info_line in (SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(null,null,'ALL')))
loop
dbms_output.put_line(info_line.plan_table_output);
end loop;
end;
使用“Y”作为参数的内存低于“N”,但排序顺序仍然是......
编辑: 忘了添加: 使用的版本是11.2.0.4
答案 0 :(得分:2)
问题是:是否有可能强迫oracle跳过 整个order by子句使用游标参数(没有动态sql 当然)?
是的,我看到另外两个解决方案,但动态sql看起来更有希望。
其他可能性:
with
子句(oracle应该在执行期间优化此查询 - 因此只查看执行计划会产生误导):with no_order as ( select /*+ gather_plan_statistics */ xes.x from ( select 1 x from dual union all select 3 x from dual union all select 2 x from dual ) xes where skip_order = 'Y' ), ordered as ( select /*+ gather_plan_statistics */ xes.x from ( select 1 x from dual union all select 3 x from dual union all select 2 x from dual ) xes where skip_order != 'Y' order by xes.x ) select * from no_order union all select * from ordered ;