如何从结果集中获得随机结果

随机

从Oracle8i开始Oracle提供采样表扫描特性。

Oracle访问数据的基本方法有:
1.全表扫描
2.采样表扫描

全表扫描(Full table Scan)
全表扫描返回表中所有的记录。
执行全表扫描,Oracle读表中的所有记录,考查每一行是否满足WHERE条件。Oracle顺序的读分配给该表的每一个数据块,这样全表扫描能够受益于多块读.
每个数据块Oracle只读一次.

采样表扫描(sample table scan)
采样表扫描返回表中随机采样数据。
这种访问方式需要在FROM语句中包含SAMPLE选项或者SAMPLE BLOCK选项.

SAMPLE选项:
当按行采样来执行一个采样表扫描时,Oracle从表中读取特定百分比的记录,并判断是否满足WHERE子句以返回结果。

SAMPLE BLOCK选项:
使用此选项时,Oracle读取特定百分比的BLOCK,考查结果集是否满足WHERE条件以返回满足条件的纪录.

Sample_Percent:
Sample_Percent是一个数字,定义结果集中包含记录占总记录数量的百分比。
Sample值应该在[0.000001,99.999999]之间。

1.使用SAMPLE选项

SQL> select * from employee SAMPLE(30); EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 7369 SMITH CLERK 7902 17-DEC-80 800 20 7788 SCOTT ANALYST 7566 19-APR-87 3000 20 7839 KING PRESIDENT 17-NOV-81 5000 10Execution Plan---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=25 Bytes=2175) 1 0 TABLE ACCESS (SAMPLE) OF 'EMPLOYEE' (Cost=2 Card=25 Bytes=2175)Statistics---------------------------------------------------------- 0 recursive calls 0 db block gets 5 consistent gets 0 physical reads 0 redo size 880 bytes sent via SQL*Net to client 503 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 3 rows processedSQL> select * from employee SAMPLE(20); EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30 7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30Execution Plan---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=16 Bytes=1392) 1 0 TABLE ACCESS (SAMPLE) OF 'EMPLOYEE' (Cost=2 Card=16 Bytes=1392)Statistics---------------------------------------------------------- 0 recursive calls 0 db block gets 5 consistent gets 0 physical reads 0 redo size 839 bytes sent via SQL*Net to client 503 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 2 rows processed

2.使用SAMPLE BLOCK选项

 

SQL> SELECT * FROM employee SAMPLE BLOCK (50); EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 7369 SMITH CLERK 7902 17-DEC-80 800 20 7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30 7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30 7566 JONES MANAGER 7839 02-APR-81 2975 20 7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30 7698 BLAKE MANAGER 7839 01-MAY-81 2850 30 7782 CLARK MANAGER 7839 09-JUN-81 2450 10 7788 SCOTT ANALYST 7566 19-APR-87 3000 20 7839 KING PRESIDENT 17-NOV-81 5000 10 7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 3010 rows selected.Execution Plan---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=41 Bytes=3567) 1 0 TABLE ACCESS (SAMPLE) OF 'EMPLOYEE' (Cost=2 Card=41 Bytes=3567)Statistics---------------------------------------------------------- 0 recursive calls 0 db block gets 4 consistent gets 0 physical reads 0 redo size 1162 bytes sent via SQL*Net to client 503 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 10 rows processedSQL>

3.采样前n条记录的查询

也可以使用dbms_random包实现

 

SQL> select * from ( 2 select * from employee 3 order by dbms_random.value ) 4 where rownum <= 4; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30 7839 KING PRESIDENT 17-NOV-81 5000 10 7369 SMITH CLERK 7902 17-DEC-80 800 20 7788 SCOTT ANALYST 7566 19-APR-87 3000 20Execution Plan---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 COUNT (STOPKEY) 2 1 VIEW 3 2 SORT (ORDER BY STOPKEY) 4 3 TABLE ACCESS (FULL) OF 'EMPLOYEE'Statistics---------------------------------------------------------- 0 recursive calls 0 db block gets 3 consistent gets 0 physical reads 0 redo size 927 bytes sent via SQL*Net to client 503 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 1 sorts (memory) 0 sorts (disk) 4 rows processed

对比一下SAMPLE选项

 

SQL> SELECT * FROM employee SAMPLE (40); EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30 7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30 7698 BLAKE MANAGER 7839 01-MAY-81 2850 30 7839 KING PRESIDENT 17-NOV-81 5000 10 7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30Execution Plan---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=33 Bytes=2871) 1 0 TABLE ACCESS (SAMPLE) OF 'EMPLOYEE' (Cost=2 Card=33 Bytes=2871)Statistics---------------------------------------------------------- 0 recursive calls 0 db block gets 5 consistent gets 0 physical reads 0 redo size 961 bytes sent via SQL*Net to client 503 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 5 rows processedSQL>

主要注意以下几点:

1.sample只对单表生效,不能用于表连接和远程表
2.sample会使SQL自动使用CBO

 

 

本文作者:
eygle,Oracle技术关注者,来自中国最大的Oracle技术论坛itpub.
www.eygle.com是作者的个人站点.你可通过Guoqiang.Gai@gmail.com来联系作者.欢迎技术探讨交流以及链接交换.

原文出处:

http://www.eygle.com/sql/How.To.Get.Random.Output.Of.Record.Set.htm

 

时间: 2024-12-21 15:38:54

如何从结果集中获得随机结果的相关文章

分布式存储数据库的Key的随机分布(RP)和顺序分布(OPP)

在分布式存储数据库的世界中,无论是基于Key/Value的数据库还是Column Base(比如HBase)的数据库,都有一个重要的因子------Key,或者叫RowKey.我们总是根据Key来快速的获取存储的数据.毫不夸张的说,Key是读数据的基础. 对于Key的存储,有两种截然不同的分布方式,我们称之为:随机分布(RP)和顺序分布(OPP) RP和OPP之间并没有绝对的优劣,不能直接断定谁比谁好,只能说是否适合当前的业务场景.在这篇文章中我们希望能够讨论一下两种方式的优劣: OPP 我们先

随机游走-C++使用 armadillo fuction——谁来解释下代码的含义?!!

问题描述 C++使用 armadillo fuction--谁来解释下代码的含义?!! 这是一个随机游走的算法代码,求相似度矩阵的 但是代码米有看懂,谁能一句一句的解释下啊?--谢谢咯! 附: arma::colvec degree = arma::sum(m_matWeight, 1); arma::mat matD = arma::diagmat(degree); m_matP = arma::solve(matD, m_matWeight); m_matB += m_matP; 重点是su

link中混编数组,如何指定不同的混填比率,并且产生的数据要充分的随机?

问题描述 link中混编数组,如何指定不同的混填比率,并且产生的数据要充分的随机? link中混编数组,如何指定不同的混填比率,并且产生的数据要充分的随机? 解决方案 可以产生一个0~1的浮点数,并且根据你要的比率,比如说0.3/0.7,那么如果它小于0.3,就从第一个取,如果这个随机数大于0.3,就从第二个取 解决方案二: 充分随机,就是在一般随机的基础上增加算法,是其均匀分布.

如何在java中实现读取一个txt文档中的随机一行

问题描述 如何在java中实现读取一个txt文档中的随机一行 如题,如何在java中实现读取一个txt文档中的随机一行? 主要就是怎么随机读取 解决方案 根据楼上的说法,来总结一下吧,总体来说,就是将文件全部都读取出来,每一行存储到一个数组或集合中,然后再通过产生随机数,来对这个数组或是 集合进行随机的访问.这样一来就解决了 解决方案二: 文本文件只能顺序读,不能随机读.你的需求只能是读取文本文件每一行到一个arraylist,然后得到下标范围,产生一个随机数,取那一行 解决方案三: http:

随机io-Go语言标准库文件随机IO带缓存么?

问题描述 Go语言标准库文件随机IO带缓存么? 就是说,func (f *File) ReadAt(b []byte off int64) (n int err error)func (f *File) WriteAt(b []byte off int64) (n int err error)这两个函数在标准库中,有没有带缓冲区?底层是用的C的标准IO(带缓冲区)么? 解决方案 用bufiohttp://golang.org/pkg/bufio/ 解决方案二: 谢谢,bufio顾名思意是带buf

在unity中用c#脚本控制物体的随机落下

问题描述 在unity中用c#脚本控制物体的随机落下 我想用Unity3d 做了一个场景,20s倒计时,当时间一到,天空开始随机不停的降落物体(这个物体可以是一个Cube),越到后面,物体下落的速度越快.时间不到,物体就不降落.这个用脚本要如何写呢? 解决方案 你可以这样试试:先去做一个要掉落的物体Cube ,然后将它存成一个Prefab在生成的Script 里面去检测时间(涉及Time),一旦20s到了之后,去执行一个for loop(i~n)loop里面用 Instantiate 生成随机位

随机产生单词然后判别其是否是真正的(可拼写的)单词:)

    linux下带的好玩小巧的东东就是多啊!本猫又找到一个spell程序,如果单词是可拼写的则神马也不输出,否则输出疑似拼错的单词.可以把若干单词放在文件中,也可以用管道输入spell.为了简便本猫采用了后一种方法,可能会慢一点啊!稍后会实现前一种方法,看看效率提高了多少.     首先是随机生成单词的方法: def rand_words(n=10000,min_len=2,max_len=12) chars = (("a".."z").to_a * max_l

php实现动态随机验证码机制

  验证码(CAPTCHA)是"Completely Automated Public Turing test to tell Computers and Humans Apart"(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序.可以防止:恶意破解密码.刷票.论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,实际上用验证码是现在很多网站通行的方式,我们利用比较简易的方式实现了这个功能.         这个

生成随机字符串和验证码的类的PHP实例

 这篇文章主要介绍了生成随机字符串和验证码的类的PHP实例,有需要的朋友可以参考一下 网上有很多的php随机数与验证码的代码与文章,真正适用的没有几个.   索性自己搞一个吧.   开始本节的php教程 吧,以下代码的实现,主要做到可以很好区分一个get_code(),另一个create_check_image(),输出图像直接调用后面的,session()取验证码时直接get_code()就ok,顺带提下使用session时必须将session_star()放在最前面.   代码如下:   代

shell如何生成指定范围随机数与随机字符串

1.使用系统的 $RANDOM 变量 fdipzone@ubuntu:~$ echo $RANDOM 17617 $RANDOM 的范围是 [0, 32767] 如需要生成超过32767的随机数,可以用以下方法实现. 例:生成400000~500000的随机数 #!/bin/bash function rand(){ min=$1 max=$(($2-$min+1)) num=$(($RANDOM+1000000000)) #增加一个10位的数再求余 echo $(($num%$max+$min