使用 DBMS_RANDOM 包对记录进行排序,然后使用行限制子句来限制所需的样本大小
dbms_random.value 函数为表中的所有行获取一个介于 0 和 1 之间的随机数,我们按照随机值的升序排序。
以下是如何生成您确定的样本集:
SELECT
*
FROM
(
SELECT
*
FROM
tbl1
ORDER BY dbms_random.value
)
FETCH FIRST 1000000 ROWS ONLY;
为了演示示例模式表emp
,我们采样了 4 条记录:
SCOTT@DEV> SELECT
2 empno,
3 rnd_val
4 FROM
5 (
6 SELECT
7 empno,
8 dbms_random.value rnd_val
9 FROM
10 emp
11 ORDER BY rnd_val
12 )
13 FETCH FIRST 4 ROWS ONLY;
EMPNO RND_VAL
7698 0.06857749035643605682648168347885993709
7934 0.07529612360785920635181751566833986766
7902 0.13618520865865754766175030040204331697
7654 0.14056380246495282237607922497308953768
SCOTT@DEV> SELECT
2 empno,
3 rnd_val
4 FROM
5 (
6 SELECT
7 empno,
8 dbms_random.value rnd_val
9 FROM
10 emp
11 ORDER BY rnd_val
12 )
13 FETCH FIRST 4 ROWS ONLY;
EMPNO RND_VAL
7839 0.00430658806761508024693197916281775492
7499 0.02188116061148367312927392115186317884
7782 0.10606515700372416131060633064729870016
7788 0.27865276349549877512032787966777990909
对于上面的示例,请注意empno
在 SQL*Plus 命令的执行过程中发生了显着的变化。
性能可能是您描述的行数的问题。
编辑:
对于 150 gigs - 79 MM 的桌子大小,任何排序都会很痛苦。
如果表有一个基于递增 1 的序列的代理键,我们可以采用基于该键选择每 n 条记录的方法。
例如
--scenario n = 3000
FROM
tbl1
WHERE
mod(table_id, 3000) = 0;
这种方法不会使用索引(除非创建了基于函数的索引),但至少我们不会对这种大小的数据集执行排序。
我对具有近 8000 万条记录的表执行了解释计划,并且它确实执行了全表扫描(条件强制执行此操作而没有基于函数的索引)但这看起来是站得住脚的。