zoukankan      html  css  js  c++  java
  • 表访问方式---->通过ROWID访问表(table access by ROWID)

    通过ROWID访问表(table access by ROWID)

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

    ROWID扫描是指Oracle在访问目标表里的数据时,直接通过数据所在的ROWID去定位并访问这些数据。

    从严格意义上来说,Oracle中的ROWID扫描有两层含义:一种是根据用户在SQL语句中输入的ROWID的值直接去访问对应的数据行记录;另外一种是先去访问相关的索引,然后根据访问索引后得到的ROWID再回表去访问对应的数据行记录。

    对Oracle中的堆表而言,我们可以通过Oracle内置的ROWID伪列得到对应行记录所在的ROWID的值(注意,这个ROWID只是一个伪 列,在实际的表块中并不存在该列),然后我们还可以通过DBMS_ROWID包中的相关方法(dbms_rowid.rowid_object,dbms_rowid.rowid_relative_fno、dbms_rowid.rowid_block_number和 dbms_rowid.rowid_row_number)将上述ROWID伪列的值翻译成对应数据行的实际物理存储地址。

    参考:Oracle中的rowid

    我们来看一个使用ROWID伪列和DBMS_ROWID包的实例。执行如下SQL,查询表EMP中的所有记录:

    SCOTT@PDBORCL>  select empno, ename, rowid, dbms_rowid.rowid_object(rowid)||'_'||dbms_rowid.rowid_relative_fno(rowid) ||
     '_' || dbms_rowid.rowid_block_number(rowid) || '_' || dbms_rowid.rowid_row_number(rowid) location from emp;
    
         EMPNO ENAME      ROWID              LOCATION
    ---------- ---------- ------------------ -------------------------------------------------------------------------------
    ------------------------------------------------------------------------------------
          7369 SMITH      AAAWh/AAJAAAACVAAA 92287_9_149_0
          7499 ALLEN      AAAWh/AAJAAAACVAAB 92287_9_149_1
          7521 WARD       AAAWh/AAJAAAACVAAC 92287_9_149_2
          7566 JONES      AAAWh/AAJAAAACVAAD 92287_9_149_3
          7654 MARTIN     AAAWh/AAJAAAACVAAE 92287_9_149_4
          7698 BLAKE      AAAWh/AAJAAAACVAAF 92287_9_149_5
          7782 CLARK      AAAWh/AAJAAAACVAAG 92287_9_149_6
          7788 SCOTT      AAAWh/AAJAAAACVAAH 92287_9_149_7
          7839 KING       AAAWh/AAJAAAACVAAI 92287_9_149_8
          7844 TURNER     AAAWh/AAJAAAACVAAJ 92287_9_149_9
          7876 ADAMS      AAAWh/AAJAAAACVAAK 92287_9_149_10
          7900 JAMES      AAAWh/AAJAAAACVAAL 92287_9_149_11
          7902 FORD       AAAWh/AAJAAAACVAAM 92287_9_149_12
          7934 MILLER     AAAWh/AAJAAAACVAAN 92287_9_149_13
    
    已选择 14 行。
    
    SCOTT@PDBORCL>

    从上述显示的内容中我们可以看出,EMPNO为7369的行记录所对应的ROWID伪列的值为"AAAWh/AAJAAAACVAAA",使用 DBMS_ROWID包对该伪列翻译后的值为"92287_9_149_0",这表示EMPNO为7369的行记录,对象编号为92287,实际的物理存储地址位于9号文件的第149个数据块的第0行记录(数据块里数据行记录的记录号从0开始算起)。

    select file_name,file_id,relative_fno from dba_data_files where relative_fno=9;

    SYS@PDBORCL> select file_name,file_id,relative_fno from dba_data_files where relative_fno=9;
    
    FILE_NAME                                                                        FILE_ID     RELATIVE_FNO
    -----------------------------------------------------------------------------------------------------------------------------------------------C:APPORACLEORADATAORCLPDBORCLSAMPLE_SCHEMA_USERS01.DBF                         9            9

    上述ROWID伪列的值是可以直接在SQL语句的where条件中使用的,这就是Oracle中ROWID扫描的两层含义中的第一种:根据用户在SQL语句中输入的ROWID的值直接去访问对应的数据行记录。

    现在执行一次如下使用ROWID伪列的SQL:

    SCOTT@PDBORCL> select empno,ename from emp where rowid='AAAWh/AAJAAAACVAAA';
    
         EMPNO ENAME
    ---------- ----------
          7369 SMITH

    从上述显示的内容中我们可以看出,Oracle确实是通过ROWID伪列(即rowid='AAAWh/AAJAAAACVAAA')直接访问到了EMPNO为7369的行记录。

    执行计划如下:

    image

    查询计划中说明该查询是的表访问方式是”TABLE ACCESS BY USER ROWID“,也就是直接通过USER ROWID来访问

    参考:

    Oracle中的rowid

    ROWID扫描

    Oracle ROWID 方式访问数据库

  • 相关阅读:
    积跬步,聚小流------关于UML类图
    深度学习 Deep Learning UFLDL 最新 Tutorial 学习笔记 1:Linear Regression
    数字语音信号处理学习笔记——语音信号的短时频域分析(2)
    PHP程序猿必须学习的第二课——站点安全问题预防
    Connection for controluser as defined in your configuration failed.
    NYOJ 76 超级台阶
    单片机小白学步系列(十) 单片机程序下载相关知识
    SQL 语言划分
    UVA 11754
    客户端远程方法声明
  • 原文地址:https://www.cnblogs.com/xqzt/p/4464205.html
Copyright © 2011-2022 走看看