表訪問方式---->通過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:\APP\ORACLE\ORADATA\ORCL\PDBORCL\SAMPLE_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 方式訪問數據庫


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM