how to make selecting random rows in oracle faster with table with millions of rows

前端 未结 7 1139
后悔当初
后悔当初 2021-02-13 11:25

Is there a way to make selecting random rows faster in oracle with a table that has million of rows. I tried to use sample(x) and dbms_random.value and its taking a long time to

7条回答
  •  遇见更好的自我
    2021-02-13 12:04

    Here's the same question on AskTom:

    http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:6075151195522

    If you know how big your table is, use sample block as described above. If you don't, you can modify the routine below to get however many rows you want.

    Copied from: http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:6075151195522#56174726207861

    create or replace function get_random_rowid
    ( table_name varchar2
    ) return urowid
    as
    sql_v varchar2(100);
    urowid_t dbms_sql.urowid_table;
    cursor_v integer;
    status_v integer;
    rows_v integer;
    begin
      for exp_v in -6..2 loop
        exit when (urowid_t.count > 0);
        if (exp_v < 2) then
          sql_v := 'select rowid from ' || table_name
          || ' sample block (' || power(10, exp_v) || ')';
        else
          sql_v := 'select rowid from ' || table_name;
        end if;
        cursor_v := dbms_sql.open_cursor;
        dbms_sql.parse(cursor_v, sql_v, dbms_sql.native);
        dbms_sql.define_array(cursor_v, 1, urowid_t, 100, 0);
        status_v := dbms_sql.execute(cursor_v);
        loop
          rows_v := dbms_sql.fetch_rows(cursor_v);
          dbms_sql.column_value(cursor_v, 1, urowid_t);
          exit when rows_v != 100;
        end loop;
        dbms_sql.close_cursor(cursor_v);
      end loop;
      if (urowid_t.count > 0) then
        return urowid_t(trunc(dbms_random.value(0, urowid_t.count)));
      end if;
      return null;
    exception when others then
      if (dbms_sql.is_open(cursor_v)) then
        dbms_sql.close_cursor(cursor_v);
      end if;
      raise;
    end;
    /
    show errors
    

提交回复
热议问题