oracle随机取行语句
oracle随机取行语句
Oracle访问数据的基本方法有:
1.全表扫描
2.采样表扫描
www.zzzyk.com
全表扫描(Full table Scan)
全表扫描返回表中所有的记录。
执行全表扫描,Oracle读表中的所有记录,考查每一行是否满足WHERE条件。Oracle顺序的读分配给该表的每一个数据块,这样全表扫描能够受益于多块读.
每个数据块Oracle只读一次.
采样表扫描(sample table scan)
采样表扫描返回表中随机采样数据。
这种访问方式需要在FROM语句中包含SAMPLE选项或者SAMPLE BLOCK选项.
SAMPLE选项: 当按行采样来执行一个采样表扫描时,Oracle从表中读取特定百分比的记录,并判断是否满足WHERE子句以返回结果。
使用采样扫描方式,会自动触发oracle的优化器CBO。
www.zzzyk.com
100万数据,使用 sample方式时 平均15-31毫秒就可以返回记录,而使用order by dbms_random.random则平均需要400毫秒
Sql代码
SELECT accountnumber, batchno, sequence
FROM e_pin
WHERE sequence=
(SELECT sequence FROM
(SELECT sequence FROM e_pin WHERE salecardflag='0' AND rownum<1000 ORDER BY dbms_random.random) WHERE rownum=1);
SELECT accountnumber, batchno, sequence FROM e_pin sample(10) where salecardflag='0' and rownum<=1;
存储过程:
Sql代码
CREATE OR REPLACE PROCEDURE p_e_pin(
i_result OUT NUMBER,
s_accountnumber OUT VARCHAR2,
s_batchno OUT VARCHAR2,
s_sequence OUT VARCHAR2
)
AS
no_evoucher EXCEPTION;
BEGIN
i_result:=0;
BEGIN
SELECT accountnumber, batchno, sequence
INTO s_accountnumber, s_batchno, s_sequence
FROM u_uvc_evoucher sample(10) where salecardflag='0' and rownum<=1 FOR UPDATE skip locked;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE no_evoucher;
END;
UPDATE e_pin SET salecardflag='4' WHERE sequence = s_sequence AND salecardflag='0';
IF SQL%NOTFOUND THEN
RAISE no_evoucher;
END IF;
COMMIT;
EXCEPTION
WHEN no_evoucher THEN
i_result:=-1;
s_accountnumber:='';
s_batchno:='';
s_sequence:='';
ROLLBACK;
END p_e_pin;
/