Oracle索引梳理系列(一)- Oracle訪問數據的方法


版權聲明本文發布於http://www.cnblogs.com/yumiko/,版權由Yumiko_sunny所有,歡迎轉載。轉載時,請在文章明顯位置注明原文鏈接。若在未經作者同意的情況下,將本文內容用於商業用途,將保留追究其法律責任的權利。如果有問題,請以郵箱方式聯系作者(793113046@qq.com)。

 


 

Oracle訪問數據的方法

Oracle訪問數據主要通過三種辦法實現: 

  1. 通過全表掃描的方式訪問數據 
  2. 通過ROWID訪問數據 
  3. 通過索引的方式訪問數據

 


 

1.1 通過全表掃描訪問表(TABLE ACCESS FULL)

  1. oracle順序讀取表中所有的行,並逐條匹配WHERE限定條件。
  2. 采用多塊讀的方式進行全表掃描,可以有效提高系統的吞吐量,降低I/O次數。
  3. 即使創建索引,oracle也會根據CBO的計算結果,決定是否使用索引。

 

注意事項:

  1. 只有全表掃描時才可以使用多塊讀。該方式下,單個數據塊僅訪問一次。
  2. 對於數據量較大的表,不建議使用全表掃描進行訪問。
  3. 當訪問表中的數據量超過數據總量的5%—10%時,通常oracle會采用全表掃描的方式進行訪問。
  4. 並行查詢可能會導致優化器選擇全表掃描的方式。

 

示例:

Yumiko@sunny >set autotrace traceonly
Yumiko@sunny >select * from scott.emp; 已選擇14行。 執行計划 ---------------------------------------------------------- Plan hash value: 3956160932 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 14 | 518 | 3 (0)| 00:00:01 | | 1 | TABLE ACCESS FULL| EMP | 14 | 518 | 3 (0)| 00:00:01 | -------------------------------------------------------------------------- 統計信息 ---------------------------------------------------------- 0 recursive calls 0 db block gets 8 consistent gets 0 physical reads 0 redo size 1539 bytes sent via SQL*Net to client 492 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 14 rows processed

其中,紅色的“TABLE ACCESS FULL”表示采用的全表掃描。

 


 

1.2 通過ROWID訪問表(TABLE ACCESS BY ROWID)

  1. ROWID是數據存放在數據庫中的物理地址,能夠唯一標識表中的一條數據。
  2. ROWID指出了一條記錄所在的數據文件、塊號以及行號的位置,因此通過ROWID定位單行數據是最快的方法。

 

注意事項:

  1. ROWID作為一個偽列,其數值並不存儲在數據庫中,當查詢時才進行計算。
  2. ROWID除了在同一集簇中可能不唯一外,每條記錄的ROWID唯一。

 

示例:

--查詢記錄的rowid
Yumiko@sunny >select rowid,ename from scott.emp where ename='SMITH'; ROWID ENAME ------------------ ---------- AAAVREAAEAAAACXAAA SMITH --利用rowid查詢數據 Yumiko@sunny >set autotrace on Yumiko@sunny >select empno,ename from scott.emp where rowid='AAAVREAAEAAAACXAAA'; EMPNO ENAME ---------- ---------- 7369 SMITH 執行計划 ---------------------------------------------------------- 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 | ----------------------------------------------------------------------------------- 統計信息 ---------------------------------------------------------- 0 recursive calls 0 db block gets 1 consistent gets 0 physical reads 0 redo size 598 bytes sent via SQL*Net to client 520 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed

其中,紅色的“TABLE ACCESS BY USER ROWID”表示采用ROWID方式訪問數據。

 


1.3 通過INDEX訪問表

  1. 通過索引查找相應數據行的rowid,再根據rowid查找表中實際數據的方式稱為“索引查找”或者“索引掃描”。
  2. 一個rowid對應一條數據行(根據rowid查找結果,僅需要對rowid相應數據的數據塊進行一次I/O操作),因此該方式屬於“單塊讀”。
  3. 對於索引,除了存儲索引的數據外,還保存有該數據對應的rowid信息。
  4. 索引掃描分為兩步:1)掃描索引確定相應的rowid信息。    2)根據rowid從表中獲得對應的數據。

 

注意事項:

  1. 對於選擇性高的數據行,索引的使用會提升查詢的性能。但對於DML操作,尤其是批量數據的操作,可能會導致性能的降低。
  2. 全表掃描的效率不一定比索引掃描差,關鍵看數據在數據塊上的具體分布。

 

示例: 

--查看目標用戶的索引對象及其名稱
Yumiko@sunny >select owner,object_name,object_type from dba_objects where owner='SCOTT'; OWNER OBJECT_NAME OBJECT_TYPE ------------------------------ -------------------- ------------------- SCOTT PK_DEPT INDEX SCOTT DEPT TABLE SCOTT EMP TABLE SCOTT PK_EMP INDEX SCOTT BONUS TABLE SCOTT SALGRADE TABLE
--查看目標索引所在的表及其列信息
Yumiko
@sunny >select index_name,table_name,column_name from dba_ind_columns where index_name='PK_EMP'; INDEX_NAME TABLE_NAME COLUMN_NAME ------------------------------ ------------------------------ -------------------- PK_EMP EMP EMPNO
--打開會話跟蹤 Yumiko
@sunny >set autotrace on



--使用索引列執行查詢並查看執行計划
Yumiko
@sunny >select empno,ename from scott.emp where empno='7369'; EMPNO ENAME ---------- ---------- 7369 SMITH 執行計划 ---------------------------------------------------------- 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) 統計信息 ---------------------------------------------------------- 1 recursive calls 0 db block gets 2 consistent gets 1 physical reads 0 redo size 598 bytes sent via SQL*Net to client 520 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed

 上面紅色的“INDEX UNIQUE SCAN”表示采用了索引掃描。同時根據執行計划,可以清晰地看到索引掃描的執行路徑,既先進行索引掃描,然后根據得到的rowid信息進行表數據的訪問。

 


免責聲明!

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



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