Oracle ROWID 方式访问数据库

    和ROWNUM一样,ROWID是一个伪列,即是一个非用户定义的列,而又实际存储于数据库之中。每一个表都有一个ROWID列,一个ROWID值用于
唯一确定数据库表中的的一条记录。因此通过ROWID 方式来访问数据也是 Oracle 数据库访问数据的实现方式之一。一般情况下,ROWID方式的
访问一定以索引访问或用户指定ROWID作为先决条件,因为所有的索引访问方式最终都会转换为通过ROWID来访问数据记录。(注:index full
scan 与index fast full scan
除外)由于Oracle ROWID能够直接定位一条记录,因此使用ROWID方式来访问数据,极大提高数据的访问效率。

-->查看表上rowid
scott@CNMMBO> select rowid,empno,ename from emp where deptno=20;

ROWID                   EMPNO ENAME
------------------ ---------- ----------
AAATTBAALAAAAuUAAA       7369 SMITH
AAATTBAALAAAAuUAAD       7566 JONES
AAATTBAALAAAAuUAAH       7788 SCOTT
AAATTBAALAAAAuUAAK       7876 ADAMS
AAATTBAALAAAAuUAAM       7902 FORD				

-->下面使用rowid来进行访
-->以下演示中忽略了物理读,仅考虑逻辑读的情形
scott@CNMMBO> set autot trace;
scott@CNMMBO> select empno,ename from emp where rowid='AAATTBAALAAAAuUAAA';

Execution Plan
----------------------------------------------------------
Plan hash value: 1116584662
-----------------------------------------------------------------------------------
| Id  | Operation                  | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |      |     1 |    22 |     1   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY USER ROWID| EMP  |     1 |    22 |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          1  consistent gets
          0  physical reads

--此时执行计划中操作1为TABLE
ACCESS BY USER ROWID,注意此时为USER ROWID,表明由用户直接调用产生
--统计信息中的consistent gets为1,即只需要根据rowid即可返回数据 

--使用多个rowid的情形
scott@CNMMBO> select empno,ename from emp where rowid in ('AAATTBAALAAAAuUAAA','AAATTBAALAAAAuUAAD');

Execution Plan
----------------------------------------------------------
Plan hash value: 1106538681
------------------------------------------------------------------------------------
| Id  | Operation                   | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |      |     1 |    22 |     1   (0)| 00:00:01 |
|   1 |  INLIST ITERATOR            |      |       |       |            |          |
|   2 |   TABLE ACCESS BY USER ROWID| EMP  |     1 |    22 |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          2  consistent gets
          0  physical reads

--上面的执行计划中出现了INLIST ITERATOR,即INLIST迭代,该操作说明其子操作多次重复时,会出现该操作。
--由于我们使用了in运算,且传递了2个rowid,故出现INLIST迭代操作
--迭代操作意味着条件中的对象列表一个接一个的迭代传递给子操作
--此时统计信息中的consistent gets为2,因为一个rowid一次逻辑运算

--下面来看看直接使用列来访问表的情形
scott@CNMMBO> select empno,ename from emp where empno=7369;

Execution Plan
----------------------------------------------------------
Plan hash value: 2949544139
--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     1 |    10 |     1   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    10 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | PK_EMP |     1 |       |     0   (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("EMPNO"=7369)
Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          2  consistent gets
          0  physical reads

--在通过谓词访问表时,此执行计划中使用了INDEX UNIQUE SCAN扫描方式
--此时先实施INDEX UNIQUE SCAN,然后将该操作的结果传递给父操作TABLE ACCESS BY INDEX ROWID来定位记录
--此时也给出了谓词信息:2 - access("EMPNO"=7369)
--此时的逻辑读consistent gets的值是2,即一次读索引,一次通过rowid读表上的数据块

--下面来看看直接使用列且使用in访问多条记录的情形
scott@CNMMBO> select empno,ename from emp where empno in (7369,7566);

Execution Plan
----------------------------------------------------------
Plan hash value: 1899965127
---------------------------------------------------------------------------------------
| Id  | Operation                    | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |        |     2 |    20 |     2   (0)| 00:00:01 |
|   1 |  INLIST ITERATOR             |        |       |       |            |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| EMP    |     2 |    20 |     2   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | PK_EMP |     2 |       |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("EMPNO"=7369 OR "EMPNO"=7566)
Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          5  consistent gets
          0  physical reads

--此时执行计划中的索引扫描方式变成了索引范围扫描INDEX RANGE SCAN
--由于存在in操作,因此此时在第2步也出现了迭代操作
--此处的逻辑读consistent gets的值是5 ?  为什么是 5 呢? 下面来分析看看

scott@CNMMBO> alter system flush shared_pool;

scott@CNMMBO> alter system flush buffer_cache;

scott@CNMMBO> set serveroutput off;
scott@CNMMBO> set autot off;
scott@CNMMBO> select /*+ gather_plan_statistics */ empno,ename from emp where empno in (7369,7566);

     EMPNO ENAME
---------- ----------
      7369 SMITH
      7566 JONES

scott@CNMMBO> select * from table(dbms_xplan.display_cursor(null,null,'iostats last'));

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------
SQL_ID  373xnw8s521t4, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ empno,ename from emp where empno in (7369,7566)

Plan hash value: 1899965127
----------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name   | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
----------------------------------------------------------------------------------------------------------
|   1 |  INLIST ITERATOR             |        |      1 |        |      2 |00:00:00.01 |       5 |      2 |
|   2 |   TABLE ACCESS BY INDEX ROWID| EMP    |      2 |      2 |      2 |00:00:00.01 |       5 |      2 |
|*  3 |    INDEX RANGE SCAN          | PK_EMP |      2 |      2 |      2 |00:00:00.01 |       3 |      1 |
----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access(("EMPNO"=7369 OR "EMPNO"=7566))

--从上面的执行计划可知,2次索引扫描,2次rowid扫描,加上1次迭代,因此总的consistent gets为5。

--与此类似的使用基于rowid的update操作,其性能同样高于直接使用列来实现update操作,此处不再演示

--使用rowid删除重复记录的示例
DELETE FROM emp e
WHERE  e.ROWID > (SELECT MIN( x.ROWID )
                 FROM   emp x
                 WHERE  x.empno = e.empno);  

--Author: Robinson Cheng
--Blog :  http://blog.csdn.net/robinson_0612

--总结:
    使用rowid访问数据时可以减少逻辑读的数量,因为一个rowid能唯一定位一条记录
    尽管rowid能极大程度的提高数据的访问效率,然而由于其不易识别性(为十六进制)在大量数据访问时并不易于使用 

更多参考

Oracle ROWID

NULL 值与索引(一)

NULL 值与索引(二)

SQL tuning 步骤

高效SQL语句必杀技

父游标、子游标及共享游标

绑定变量及其优缺点

dbms_xplan之display_cursor函数的使用

dbms_xplan之display函数的使用

执行计划中各字段各模块描述

使用 EXPLAIN PLAN 获取SQL语句执行计划

启用 AUTOTRACE 功能

函数使得索引列失效

Oracle 绑定变量窥探

Oracle 自适应共享游标              

 

时间: 2024-10-21 15:58:03

Oracle ROWID 方式访问数据库的相关文章

用ASP访问数据库的几种常见方式

用ASP访问数据库的几种常见方式 ActiveX Data Objects (ADO) 是一项容易使用并且可扩展的将数据库访问添加到 Web 页的技术.可以使用 ADO 去编写紧凑简明的脚本以便连接到 Open Database Connectivity (ODBC) 兼容的数据库和 OLE DB 兼容的数据源.如果您是一个对数据库连接有一定了解的脚本编写人员,那么您将发现 ADO 命令语句并不复杂而且容易掌握.同样地,如果您是一个经验丰富的数据库编程人员,您将会正确认识 ADO 的先进的与语言

mfc-我已经通过MFC ODBC连上mysql数据库了,怎样以最简单的方式访问到数据?

问题描述 我已经通过MFC ODBC连上mysql数据库了,怎样以最简单的方式访问到数据? 已经连上mysql了,现在只需要读出数据库里的数据就行,希望能读出某一个字段中的所有值,按顺序这样读下来,存到我的程序里,怎么读最简单?本人比较菜,最好有易懂的代码,谢谢了 解决方案 就是select * from table这样的比较的理想 解决方案二: 参考:http://www.cnblogs.com/good90/archive/2012/03/04/2379371.htmlMFC通过ODBC连接

Eclipse3.0配置SQLExplorer访问数据库

sql|访问|数据|数据库 英文原文地址: http://www.onjava.com/pub/a/onjava/2005/05/11/sqlexplorer.html中文地址: http://www.matrix.org.cn/resource/article/43/43630_Eclipse_SQLExplorer.html关键词: Eclipse SQLExplorer MySQL JDBC SQLExplorer是Eclipse集成开发环境的一种插件,它可以被用来从Eclipse连接到一

Java访问数据库的速度瓶颈问题的分析及解决

访问|解决|数据|数据库|速度|问题 内容: 速度瓶颈问题的提出 JDBC访问数据库的机制 不同模式的JDBC接口的选择 Java程序中SQL语句格式的优化 软件模型中对数据库访问的设计模式的优化 将深入研究的问题 参考资料 关于作者 FoolsGarden@SMTH 自由Java传道士 2001 年 11 月 速度瓶颈问题的提出 在企业级的Java应用中,访问数据库是一个必备的环节.数据库作为数据资源的集散地,往往位于企业级软件体系的后方,供前方的应用程序访问.在Java技术的体系中,应用程序

ASP访问数据库 如何配置数据库文件DSN

访问|数据|数据库 程序数据库类 ActiveX Data Objects (ADO) 是一项容易使用并且可扩展的将数据库访问添加到 Web 页的技术.可以使用 ADO 去编写紧凑简明的脚本以便连接到 Open Database Connectivity (ODBC) 兼容的数据库和 OLE DB 兼容的数据源.如果您是一个对数据库连接有一定了解的脚本编写人员,那么您将发现 ADO 命令语句并不复杂而且容易掌握.同样地,如果您是一个经验丰富的数据库编程人员,您将会正确认识 ADO 的先进的与语言

Oracle启动方式简介

1 .startup nomount 非安装启动,这种方式启动下可执行:重建控制文件.重建数据库 读取init.ora文件,启动instance,即启动SGA和后台进程,这种启动只需要init.ora文件. 2 .startup mount dbname 安装启动,这种方式启动下可执行: 数据库日志归档. 数据库介质恢复. 使数据文件联机或脱机, 重新定位数据文件.重做日志文件. 执行"nomount",然后打开控制文件,确认数据文件和联机日志文件的位置, 但此时不对数据文件和日志文件

windows-各位高手能推荐一款c++访问数据库的成熟的库吗,必须支持win和linux

问题描述 各位高手能推荐一款c++访问数据库的成熟的库吗,必须支持win和linux 我们公司要开发一个软件,第一个版本将在windows上运行,随后会发布linux版本,这个软件可能连接到Oracle/MySql/SqlServer等多种数据库,考虑到时间和成本的问题,我认为用现成的库要比自己开发和维护更加快捷高效(正如caozhy所说,实现这个功能必须"写一个抽象类,访问数据库.不同的数据库,继承这个抽象类,把差异的代码写在里面,使用工厂设计模式.并且把这些代码条件编译(针对windows和

集算器访问数据库的配置

集算器支持包括数据库在内的多种异构数据源.这里,我们通过例子来看一下集算器访问数据库的方法. 集算器可以连接数据库的jdbc驱动,也可以通过jdbc-odbc桥连接数据库.由于版权的原因,使用集算器的程序员需要自行准备数据库的jdbc或者odbc驱动.Jdbc驱动jar包准备好之后,需要放入集算器IDE安装目录的/common/jdbc中,例如:C:\Program Files (x86)\MicroInsight\common\jdbc目录中. 集算器集成开发环境的ODBC配置界面如下: 集算

windows-关于plsql访问数据库的时候中文乱码的问题

问题描述 关于plsql访问数据库的时候中文乱码的问题 我在linux中部署了oracle 11g R2,在本地windows中用plsql访问的时候,表中的注释出现乱码. 数据库中的编码方式是AL32UTF8,本地的环境变量也是AMERICAN_AMERICA.UTF8,注册表中也是AMERICAN_AMERICA.UTF8.但是还是出现乱码. 求高手指导.. 解决方案 打开plsql developer 找到 Tools---->preferences----->files(左手边的地方)