有条件的排序方式并最大限度地降低执行成本



我有一个非常有效的游标,但是当我打开它时,我希望它也以使其变慢的方式对行进行排序。

显而易见的解决方案是拥有游标的第二个副本,一个具有顺序,另一个没有它。

但是,这很乏味,并且将来容易出错。

问题是:是否有可能强制 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

问题是:是否有可能强制预言机跳过 使用游标参数的整个顺序依据子句(无动态 SQL 当然)?

是的,我看到了另外 2 种解决方案,但动态 sql 看起来更有希望。

其他可能性:

  1. 编写 2 个游标(带和不带排序依据)并选择要使用的游标。
  2. 使用with子句(oracle 应该在执行期间优化此查询 - 因此只查看执行计划具有误导性):
no_order为 ( 选择/*+ gather_plan_statistics */xes.x 从 ( 从双并集全部中选择 1 x  从双并集全部中选择 3 x  从双选项 2 x ) xes 其中skip_order = 'Y'  ),  排序为  (  选择/*+ gather_plan_statistics */xes.x 从 ( 从双并集全部中选择 1 x  从双并集全部中选择 3 x  从双选项 2 x ) xes 其中skip_order != 'Y' 通过 xes.x 订购  ) 选择* 从no_order 全部联合 选择* 从订购  ;

相关内容

最新更新