本文将对oracle当中扫描数据的存取方法进行介绍。

1) 全表扫描(Full Table Scans, FTS)

为实现全表扫描,Oracle读取表中所有的行,并检查每一行是否满足语句的WHERE限制条件一个多块读操作可以使一次I/O能读取多块数据块(db_block_multiblock_read_count参数设定),而不是只读取一个数据块,这极大的减少了I/O总次数,提高了系统的吞吐量,所以利用多块读的方法可以十分高效地实现全表扫描,而且只有在全表扫描的情况下才能使用多块读操作。在这种访问模式下,每个数据块只被读一次。

使用FTS的前提条件:在较大的表上不建议使用全表扫描,除非取出数据的比较多,超过总量的5% -- 10%,或你想使用并行查询功能时。

使用全表扫描的例子: 

 SQL> explain plan for select * from dual;

Query Plan

SELECT STATEMENT[CHOOSE] Cost=

TABLE ACCESS FULL DUAL

2) 通过ROWID的表存取(Table Access by ROWID或rowid lookup)

行的ROWID指出了该行所在的数据文件、数据块以及行在该块中的位置,所以通过ROWID来存取数据可以快速定位到目标数据上,是Oracle存取单行数据的最快方法。

这种存取方法不会用到多块读操作,一次I/O只能读取一个数据块。我们会经常在执行计划中看到该存取方法,如通过索引查询数据。

使用ROWID存取的方法: 

     SQL> explain plan for select * from dept where rowid = 'AAAAyGAADAAAAATAAF';

Query Plan

SELECT STATEMENT [CHOOSE] Cost=1

TABLE ACCESS BY ROWID DEPT [ANALYZED]

3)索引扫描(Index Scan或index lookup)

我们先通过index查找到数据对应的rowid值(对于非唯一索引可能返回多个rowid值),然后根据rowid直接从表中得到具体的数据,这种查找方式称为索引扫描或索引查找(index lookup)。一个rowid唯一的表示一行数据,该行对应的数据块是通过一次i/o得到的,在此情况下该次i/o只会读取一个数据库块。

在索引中,除了存储每个索引的值外,索引还存储具有此值的行对应的ROWID值。索引扫描可以由2步组成:(1) 扫描索引得到对应的rowid值。 (2) 通过找到的rowid从表中读出具体的数据。每步都是单独的一次I/O,但是对于索引,由于经常使用,绝大多数都已经CACHE到内存中,所以第1步的I/O经常是逻辑I/O,即数据可以从内存中得到。但是对于第2步来说,如果表比较大,则其数据不可能全在内存中,所以其I/O很有可能是物理I/O,这是一个机械操作,相对逻辑I/O来说,是极其费时间的。所以如果多大表进行索引扫描,取出的数据如果大于总量的5% -- 10%,使用索引扫描会效率下降很多。如下列所示: 

     SQL> explain plan for select empno, ename from emp where empno=10;

Query Plan

SELECT STATEMENT [CHOOSE] Cost=1

TABLE ACCESS BY ROWID EMP [ANALYZED]

INDEX UNIQUE SCAN EMP_I1

但是如果查询的数据能全在索引中找到,就可以避免进行第2步操作,避免了不必要的I/O,此时即使通过索引扫描取出的数据比较多,效率还是很高的

     SQL> explain plan for select empno from emp where empno=10;-- 只查询empno列值

Query Plan

SELECT STATEMENT [CHOOSE] Cost=1

INDEX UNIQUE SCAN EMP_I1

进一步讲,如果sql语句中对索引列进行排序,因为索引已经预先排序好了,所以在执行计划中不需要再对索引列进行排序

      SQL> explain plan for select empno, ename from emp

where empno > 7876 order by empno;

Query Plan

SELECT STATEMENT[CHOOSE] Cost=1

TABLE ACCESS BY ROWID EMP [ANALYZED]

INDEX RANGE SCAN EMP_I1 [ANALYZED]

从这个例子中可以看到:因为索引是已经排序了的,所以将按照索引的顺序查询出符合条件的行,因此避免了进一步排序操作。

根据索引的类型与where限制条件的不同,有4种类型的索引扫描:

索引唯一扫描(index unique scan)

索引范围扫描(index range scan)

索引全扫描(index full scan)

索引快速扫描(index fast full scan)

(1) 索引唯一扫描(index unique scan)

通过唯一索引查找一个数值经常返回单个ROWID。如果存在UNIQUE 或PRIMARY KEY 约束(它保证了语句只存取单行)的话,Oracle经常实现唯一性扫描。

使用唯一性约束的例子:

     SQL> explain plan for

select empno,ename from emp where empno=10;

Query Plan

SELECT STATEMENT [CHOOSE] Cost=1

TABLE ACCESS BY ROWID EMP [ANALYZED]

INDEX UNIQUE SCAN EMP_I1

(2) 索引范围扫描(index range scan)

使用一个索引存取多行数据,在唯一索引上使用索引范围扫描的典型情况下是在谓词(where限制条件)中使用了范围操作符(如>、<、<>、>=、<=、between)

使用索引范围扫描的例子:

      SQL> explain plan for select empno,ename from emp

where empno > 7876 order by empno;

Query Plan

SELECT STATEMENT[CHOOSE] Cost=1

TABLE ACCESS BY ROWID EMP [ANALYZED]

INDEX RANGE SCAN EMP_I1 [ANALYZED]

在非唯一索引上,谓词col = 5可能返回多行数据,所以在非唯一索引上都使用索引范围扫描。

使用index rang scan的3种情况:

(a) 在唯一索引列上使用了range操作符(> < <> >= <= between)

(b) 在组合索引上,只使用部分列进行查询,导致查询出多行

(c) 对非唯一索引列上进行的任何查询。

(3) 索引全扫描(index full scan)

与全表扫描对应,也有相应的全索引扫描。而且此时查询出的数据都必须从索引中可以直接得到。

全索引扫描的例子:

An Index full scan will not perform single block i/o's and so it may prove to be inefficient.

e.g.

Index BE_IX is a concatenated index on big_emp (empno, ename)

SQL> explain plan for select empno, ename from big_emp order by empno,ename;

Query Plan

SELECT STATEMENT[CHOOSE] Cost=26

INDEX FULL SCAN BE_IX [ANALYZED]

(4) 索引快速扫描(index fast full scan)

扫描索引中的所有的数据块,与 index full scan很类似,但是一个显著的区别就是它不对查询出的数据进行排序,即数据不是以排序顺序被返回。在这种存取方法中,可以使用多块读功能,也可以使用并行读入,以便获得最大吞吐量与缩短执行时间。

索引快速扫描的例子:

BE_IX索引是一个多列索引: 

     big_emp (empno,ename)

SQL> explain plan for select empno,ename from big_emp;

Query Plan

SELECT STATEMENT[CHOOSE] Cost=1

INDEX FAST FULL SCAN BE_IX [ANALYZED]

只选择多列索引的第2列:

     SQL> explain plan for select ename from big_emp;

Query Plan

SELECT STATEMENT[CHOOSE] Cost=1

INDEX FAST FULL SCAN BE_IX [ANALYZED]

【转】Oracle当中扫描数据的方法的更多相关文章

  1. Oracle导入excel数据快速方法

    Oracle导入excel数据快速方法 使用PLSQL  Developer工具,这个可是大名鼎鼎的Oracle  DBA最常使用的工具.    在单个文件不大的情况下(少于100000行),并且目的 ...

  2. 恢复oracle数据库误删除数据的方法汇总

    学习数据库时,我们只是以学习的态度,考虑如何使用数据库命令语句,并未想过工作中,如果误操作一下,都可能导致无可挽回的损失.当我在工作中真正遇到这些问题时,我开始寻找答案.今天主要以oracle数据库为 ...

  3. oracle常用的数据迁移方法

    源地址:http://wenku.baidu.com/link?url=lI6UYpvDs_y8ku6DytEZLl4GSJjQ0GAGPvv8txrbRoQKgqzTCMAfBZI5mn9t-KQk ...

  4. Oracle 拼接列数据的方法

    select wm_concat(fphone) phone from dq_phone_ndtbdxz wm_concat(列名):把多列值,合并成一列,用,隔开.

  5. Oracle优化器基础知识之访问数据的方法

    目录 一.访问数据的方法 1.直接访问数据 2.访问索引 一.访问数据的方法 Oracle访问表中数据的方法有两种,一种是直接表中访问数据,另外一种是先访问索引,如果索引数据不符合目标SQL,就回表, ...

  6. C#连接Oracle数据库查询数据

    C#连接Oracle数据库可以实现许多我们需要的功能,下面介绍的是C#连接Oracle数据库查询数据的方法,如果您对C#连接Oracle数据库方面感兴趣的话,不妨一看. using System; u ...

  7. Oracle索引梳理系列(一)- Oracle访问数据的方法

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

  8. Oracle 优化器_访问数据的方法_单表

    Oracle 在选择执行计划的时候,优化器要决定用什么方法去访问存储在数据文件中的数据.我们从数据文件中查询到相关记录,有两种方法可以实现:1.直接访问表记录所在位置.2.访问索引,拿到索引中对应的r ...

  9. Oracle 列数据聚合方法汇总

    网上流传众多列数据聚合方法,现将各方法整理汇总,以做备忘. wm_concat 该方法来自wmsys下的wm_concat函数,属于Oracle内部函数,返回值类型varchar2,最大字符数4000 ...

随机推荐

  1. live555在Raspberry Pi上的点播/直播

    1.live555在Raspberry Pi上的点播 live555MediaServer这个实例是个简单的服务器,支持多媒体点播,直接在Raspberry Pi上编译运行,或者通过交叉编译出ARM核 ...

  2. Quagga服务器安装和配置

    使用本地源 一.安装软件包 # yum install quagga-0.99.15-7.el6_3.2.x86_64.rpm 或rpm   # ls /etc/quagga/ bgpd.conf.s ...

  3. ASP.NET MVC WebGrid – Performing true AJAX pagination and sorting 【转】

    ASP.NET MVC WebGrid – Performing true AJAX pagination and sorting FEBRUARY 27, 2012 14 COMMENTS WebG ...

  4. ASP.NET MVC使用Bootstrap系列(5)——创建ASP.NET MVC Bootstrap Helpers

    阅读目录 序言 内置的HTML Helpers 创建自定义的Helpers 使用静态方法创建Helpers 使用扩展方法创建Helpers 创建Fluent Helpers 创建自动闭合的Helper ...

  5. Serializer序列化/反序列化DateTime少了8小时问题解决

    1.举例子 JavascriptSerializer serializer = new JavascriptSerializer(); DateTime now = DateTime.Parse(&q ...

  6. webservice 服务端例子+客户端例子+CXF整合spring服务端测试+生成wsdl文件 +cxf客户端代码自动生成

    首先到CXF官网及spring官网下载相关jar架包,这个不多说.webservice是干嘛用的也不多说. 入门例子 模拟新增一个用户,并返回新增结果,成功还是失败. 大概的目录如上,很简单. Res ...

  7. 如何更好地利用Pmd、Findbugs和CheckStyle分析结果

    这里列出了很多Java静态分析工具,每一种工具关注一个特定的能发挥自己特长的领域,我们可以列举一下: Pmd 它是一个基于静态规则集的Java源码分析器,它可以识别出潜在的如下问题:– 可能的bug— ...

  8. Struts2验证框架实例

    今天写了个Struts验证框架的实例,总算把验证框架弄清楚了. 上一篇Struts实例的action没有继承ActionSupport类,虽然也可以实现action的功能,但是却不能应用Struts提 ...

  9. 贴上自己写的代码-jq隐藏事件

  10. Java实现zip压缩多个文件下载

    为了更好的演示,首先创建一个文件实体FileBean,包含了文件路径和文件名称: package com.javaweb.entity; import java.io.Serializable; /* ...