一、Oracle访问数据的基本方法:
1)、全表扫描(Full table Scan):执行全表扫描,Oracle读表中的所有记录,考查每一行是否满足WHERE条
件。Oracle顺序的读分配给该表的每一个数据块,且每个数据块Oracle只读一次.这样全表扫描能够受益于
多块读。
2)、采样表扫描(sample table scan):扫描返回表中随机采样数据,这种访问方式需要在FROM语句中包含
SAMPLE选项或者SAMPLE BLOCK选项。
二、获取随机结果集的方法:
1)、使用sample获取随机结果集
1、语法: SAMPLE [ BLOCK ](sample_percent)[ SEED (seed_value) ]
SAMPLE选项:表示按行采样来执行一个全表扫描,Oracle从表中读取特定百分比的记录,并判断是否满足
WHERE子句以返回结果。
BLOCK: 表示使用随机块例举而不是随机行例举。
sample_percent:是随机获取一张表中记录的百分比。比如值为10,那就是表中的随机的百分之10的记
录。值必须大于等于.000001,小于100。
SEED:表示从哪条记录返回,类似于预先设定例举结果,因而每次返回的结果都是固定的。该值必须介于0
和4294967295之间。
2、例子(看语法不如看例子)
--从表 zs_xj_family 中“全表扫描”随机抽取20%的记录,再从中随机查询5条记录
SELECT *
FROM zs_xj_family SAMPLE (20)
WHERE ROWNUM <= 5;
-- 从表 zs_xj_family 中“采样表扫描”随机抽取10%的记录,再从中随机查询5条记录
SELECT *
FROM zs_xj_family SAMPLE BLOCK (10)
WHERE ROWNUM <= 5;
--使用seed,返回固定的结果集。
SELECT *
FROM zs_xj_family SAMPLE (10) SEED (3)
WHERE ROWNUM <= 5
SELECT *
FROM zs_xj_family SAMPLE BLOCK (10) SEED (11)
WHERE ROWNUM <= 5;
注意:
1.sample只对单表生效,不能用于表连接、远程表、视图
2.sample会使SQL自动使用CBO
疑点:
我在测试sample 的时候发现如果我的表中数据有20条,按照它的sample值我写这样的sql: select * from
tablename sample(50) 应该结果集中的数据占总数据的50%才对,但是多次执行之后的结果却是多少数据
都有,小于50%、大于50%的都有,这跟 Sample_Percent是一个数字,定义结果集中包含记录占总记录数量
的百分比的说明不符,而且用sample block时有时候还能查询出空结果集(select * from tablename
sample block(50))
2)使用DBMS_RANDOM包
DBMS_RANDOM有两种主要的使用方法分别是:DBMS_RANDOM.VALUE()和DBMS_RANDOM.RANDOM
1、获取一个随机数
--(0-10的整数)
SELECT TRUNC (DBMS_RANDOM.VALUE (0, 10)) randomNum FROM DUAL;
--(0-100的浮点数)
SELECT DBMS_RANDOM.VALUE (0, 100) randomNum FROM DUAL;
--(0.几的小数)
SELECT DBMS_RANDOM.VALUE () randomNum FROM DUAL;
2、获取随机记录
SELECT *
FROM ( SELECT *
FROM zs_family
where is_test=1
ORDER BY DBMS_RANDOM.VALUE)
WHERE ROWNUM <= 3
SELECT *
FROM ( SELECT *
FROM zs_family
where is_test=1
ORDER BY DBMS_RANDOM.VALUE(1,3))
WHERE ROWNUM <= 3
SELECT *
FROM ( SELECT *
FROM zs_family
WHERE is_dxx = 1 AND is_test = 1
ORDER BY DBMS_RANDOM.random)
WHERE ROWNUM <= 3
3)使用内部函数sys_guid()
SELECT *
FROM ( SELECT *
FROM zs_family
WHERE is_test = 1
ORDER BY sys_guid())
WHERE ROWNUM <= 3
注意:
在使用sys_guid() 这种方法时,有时会获取到相同的记录,即和前一次查询的结果集是一样的,查找相
关资料,有些说是和操作系统有关,在windows平台下正常,获取到的数据是随机的,而在linux等平台下始
终是相同不变的数据集,有些说是因为sys_guid()函数本身的问题,即sys_guid()会在查询上生成一个 16
字节的全局唯一标识符,这个标识符在绝大部分平台上由一个宿主标识符和进程或进程的线程标识符组成,
这就是说,它很可能是随机的,但是并不表示一定是百分之百的这样。
所以,为确保在不同的平台每次读取的数据都是随机的,我们大多采用使用sample函数或者 DBMS_RANDOM
包获得随机结果集,其中使用sample函数更常用,因为其查询时缩小了查询范围,在查询大表,且要提取数
据不是很不多的情况下,会对查询速度上有明显的提高。
三、其他数据库随机取出n条记录:
1、SqlServer中随机提取数据库记录
select * from 表 order by newid()
2、mysql中随机提取数据库记录
select * from tablename order by rand() limit 10
3、Access中随机提取数据库记录
SELECT top 10 * FROM tablename ORDER BY Rnd(字段名)
相关文章
- mysql中GROUP BY分组取前N条记录实现
- [SQL Server] 从SQL Server 表中随机获取n条或百分比数据
- 向数据库中插入100万条随机姓名记录用于测试
- 数据中有上万条记录,能不用WHERE或其它的筛选条件,读取数据库中的第n条到n+100条记录呢?
- MySql 100万级别数据中随机获取一条或多条记录之RAND()优化
- 19、SQL Server / Oracle:分组排序取头条记录(搜索结果中的重复记录仅取第一条)
- 在mongo db中检索下N条记录
- Oracle、SQLServer 删除表中的重复数据,只保留一条记录
- Oracle分组查询取每组排序后的前N条记录
- SqlServer2000中如何用存储过程实现返回一个表的第N1到第N2条记录