PL/SQL 性能分页游标(带过滤和固定结果大小)

PL/SQL performance paging cursor (with filtering and fixed result size)

我有一个 pl/sql 游标,它从定义的 rowid(由参数给定)开始,用于分页查询。

游标检索的行按特殊规则过滤 - 因此结果行不会立即返回,而是收集在 table 类型变量中。

在一个循环中,我从游标中获取更多数据,直到将 100 个“行”放入 table 类型变量。此结果从函数发回。

一切正常,但初始 sql 查询(打开游标)需要很长时间。 如果我限制 sql 语句中的行(在“WHERE rownum <= (100 + p_startfrom)”中注释),查询会快得多。但是我不知道我要通过循环和过滤来获取多少数据。

有没有办法通过不添加固定的“rownum <= where 子句来使函数更快?

  function get_metadata(p_toquery in number, p_startfrom in number) return t_Table_metadata
  is
    v_result_tab t_Table_metadata;
    v_return_tab t_Table_metadata := t_Table_metadata();
    
    c_meta SYS_REFCURSOR;
    
    v_size_per_fetch integer := 100;    
  begin
    open c_meta for 
      'SELECT t_type_metadata(....)
      FROM (
        SELECT t.*, rownum r
        FROM (
          select ...
          from   ...
          where  attr1 =  '|| p_toquery||'
          order  by create_date desc
        ) t
      -- with this where-Clause much faster!! WHERE rownum <= (100 + p_startfrom)
      ) f
      WHERE r >= '|| p_startfrom;

    loop
      fetch c_meta bulk collect into v_result_tab limit v_size_per_fetch;

        for i in 1..v_result_tab.count loop

          v_check_row_result := check_row(....);

          if (v_check_row_result = 1 and v_return_tab.count < 100) then
            v_return_tab.extend;
            v_return_tab(v_return_tab.count) := v_result_tab(i);
          end if;

        end loop;

      exit when v_result_tab.count = 0 or v_return_tab.count >= 100;
    end loop;
    close c_meta;
    
    return v_return_tab;
  end;

使用提示 FIRST_ROWS 要求 Oracle 将查询快速优化为 return 少量行。您仍然需要猜测 PL/SQL 循环所需的行数,但粗略猜测,如 1000,可能就足够了。

SELECT /*+ first_rows(1000) */ t_type_metadata(....)

正如其他人评论的那样,如果您可以将所有条件放入单个 SQL 语句中,那将是理想的。使用单个 SQL 语句,添加分页可以像这样简单:select ... offset 100 rows fetch next 100 rows only;