`

oracle--随机查询

阅读更多

转自:http://1985wanggang.blog.163.com/blog/static/77638332010424102256740/

 

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                    10

 

Execution 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 processed

 

SQL> 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         30

 

Execution 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         30

 

10 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 processed

 

SQL>

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                    20

 

Execution 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         30

 

Execution 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 processed

 

SQL>

主要注意以下几点:

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


===============================
1】方法一:通过dbms_random.random

select * from (select * from largetable order by dbms_random.random) where rownum <= 20000;


2】方法二:通过dbms_random.value

select * from (select * from largetable order by dbms_random.value) where rownum <= 20000;


3】方法三:通过采样表扫描

select * from (select * from largetable sample(10)) where rownum <= 20000;


下面我们通过实践来比较这3种方法的效率,首先我们创建一个包含有10W条记录的表用于实验:

create table LARGETABLE
(
   ID       NUMBER
not null primary key,
   BIRTHDAY DATE
not null
)


接下来我们插入10W条数据

create or replace procedure random_insert as
   i         number;
   startDate date :
= sysdate;

begin

  
for i in 1 .. 100000 loop
    
insert into largetable values (i, startDate + 1);
  
end loop commit;

end;

 

 

SQL*PLUS下设置显示SQL语句执行时间:set timing on,让后分别运行上述三条语句:

第一个的执行时间为 00: 00: 16: 04
第二个的执行时间为 00: 00: 54: 04
第三个的执行时间为 00: 00: 08: 07

从这里我们可以看出在进行数据随机抽取时,采用sample的方法效率是最高的。为了保证每次随机查询的数据尽量不重复,我们可以把sample中的百分比提高一些(例如从10%提高到20%)

 

分享到:
评论

相关推荐

    oracle11g 设置随机启动

    ### Oracle 11g 设置随机启动详解 #### 标题:Oracle 11g 设置随机启动 #### 描述概述: 本文档提供了一种确保Oracle 11g数据库服务能够随系统启动而自动运行的方法。该方法经过实际测试验证,确保在设置完成后...

    oracle-18c-新特性

    近似查询技术在 Oracle 18c 中得到了进一步增强: 1. **近似查询**:允许对大型数据集进行近似统计,例如,确定唯一值的数量,这对于不需要精确结果的查询非常有用。 2. **Top-N 近似聚合**:可以在允许的小误差...

    Oracle中如何生成随机数字、随机字符串、随机日期

    Oracle中如何生成随机数字、随机字符串、随机日期 详细实例脚本。

    Oracle-ERP(NEW)笔记

    - **层次树查询**:使用Oracle层次树查询功能,高效处理具有层级关系的数据。 - **Mergeinto应用**:了解Mergeinto语句在数据合并方面的强大能力。 - **Truncate Table**:学习Truncate Table命令,快速清空表数据。...

    oracleasm-support-2.1.8-1.el5.x86_64

    2. **高性能**:通过I/O优化和缓存管理,ASM能够提高I/O操作的速度,尤其对于随机读写操作有显著提升。 3. **容错能力**:ASM支持多种冗余模式,如RAID-1(镜像)、RAID-5(分布式奇偶校验)等,能够在磁盘故障时...

    数据库-oracle-学习之路.docx

    在Oracle中,可以使用自增序列(如`GETUUID.NEXTVAL`)或随机值(如`DBMS_RANDOM.VALUE`)结合`SUBSTR`函数生成主键。 2. **数据库空间查询**: - 表空间是Oracle数据库中存储数据文件的逻辑单位,用于管理和分配...

    Padding-Oracle-Attack详解[归纳].pdf

    CBC模式引入了一个随机的初始化向量来加强密文的随机性,保证相同的明文多次加密都得到不一样的密文。 Padding Oracle Attack Padding Oracle Attack的根源在于明文分组和填充,但是需要一个前提,那就是应用程序...

    oracle-machine-learning-sql-api-guide.pdf

    Oracle支持决策树、随机森林和神经网络等算法。 2. **聚类(Clustering)**: 聚类是发现数据的自然群体或类别,无需预先设定类别。这有助于理解数据集中的结构和模式,常用于市场细分或用户行为分析。 3. **关联...

    us-18-Boeck-Young-Return-Of-Bleichenbachers-Oracle-Threat.pdf

    《Return of Bleichenbacher's Oracle Threat:TLS握手与RSA加密的安全分析》 在网络安全领域,尤其是金融安全和数据安全方面,安全防护、安全体系、网络安全、安全实践和安全管理是至关重要的元素。本文将深入探讨...

    Oracle-性能优化之-表设计(与“数据”有关文档共15张).pptx

    - 堆表是最基本的表类型,数据以随机的方式存储,没有特定的顺序。这种存储方式的优点是写入速度快,因为数据可以快速地插入到合适的位置。然而,由于缺乏预定义的顺序,查询速度通常较慢,尤其是在没有索引的情况...

    Oracle中如何生成随机数字、随机字符串、随机日期.docx

    在 Oracle 数据库中,生成随机数据对于测试、模拟或数据分析任务非常有用。下面将详细介绍如何在 Oracle 中生成随机数字、随机字符串以及随机日期。 1. 随机小数: Oracle 提供 `DBMS_RANDOM.VALUE` 这个包来生成...

    java随机生成二进制数-java–随机二进制搜索算法 随机搜索算法.pdf

    "Java 随机生成二进制数搜索算法" 在 Java 中,随机生成二进制数是一种常用的技术,用于解决搜索问题。在这里,我们将讨论一种基于随机搜索算法的解决方案,用于在数组中查找指定的值。 随机搜索算法 随机搜索...

    Oracle中如何生成随机数字、随机字符串、随机日期.pdf

    在Oracle数据库中,生成随机数据是一项常见的需求,尤其是在测试、模拟和数据分析时。Oracle提供了几个内置函数来帮助我们生成随机的小数、整数、字符串以及日期。下面我们将详细讨论这些函数的使用方法。 1. 随机...

    oracle中随机数的获取

    在Oracle数据库中,生成随机数是一项常见的需求,特别是在数据测试、模拟或数据分析场景中。本文将详细介绍如何在Oracle SQL中获取各种类型的随机数。 首先,Oracle提供了一个内置的函数DBMS_RANDOM,它包含了一...

    随机生成汉字(控制台下)

    在IT领域,编程时常需要处理各种数据生成任务,其中之一就是生成随机汉字。本文将深入探讨如何在控制台环境下实现这一功能,以及背后的汉字编码原理。 首先,我们要了解汉字的编码方式。汉字在计算机中通常使用...

    Oracle里取随机数的几种具体的方法

    5. 将临时表 tmp_1 和 tmp_2 相关联,取得符合条件的随机记录。 6. 最后,删除临时表 tmp_1、tmp_2 和序列号 tmp_id。 例如,以下是使用 DBMS_RANDOM 包生成随机数的示例代码: ```sql -- 创建序列号 tmp_id CREATE...

    oracle取随机数

    Oracle也提供了生成随机字符串的功能,主要通过`DBMS_RANDOM.STRING`函数实现,该函数接受两个参数:字符类型(如可打印字符)和长度。 ```sql SELECT DBMS_RANDOM.STRING('P', 20) FROM DUAL; ``` 其中,'P'代表...

    Oracle随机启动

    ### Oracle随机启动知识点详解 #### 一、Oracle随机启动概述 在Linux环境下,为了实现Oracle数据库服务能够在系统启动时自动启动,通常会采用特定的方法来配置。本篇将重点介绍如何通过修改`/etc/oratab`文件以及...

    Oracle插入随机数

    在Oracle数据库管理中,有时我们需要向数据库表中插入大量的随机数据来进行测试、演示或者数据模拟分析等工作。本篇文章将详细介绍如何利用自定义的Oracle函数来实现这一功能。 #### 自定义Oracle函数 为了实现向...

Global site tag (gtag.js) - Google Analytics