熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

淺談存取Oracle當中掃描數據的方法

2013-11-13 15:52:52  來源: Oracle 

  ) 全表掃描(Full Table Scans FTS)

  為實現全表掃描Oracle讀取表中所有的行並檢查每一行是否滿足語句的WHERE限制條件一個多塊讀操作可以使一次I/O能讀取多塊數據塊(db_block_multiblock_read_count參數設定)而不是只讀取一個數據塊這極大的減少了I/O總次數提高了系統的吞吐量所以利用多塊讀的方法可以十分高效地實現全表掃描而且只有在全表掃描的情況下才能使用多塊讀操作在這種訪問模式下每個數據塊只被讀一次

  使用FTS的前提條件在較大的表上不建議使用全表掃描除非取出數據的比較多超過總量的% %或你想使用並行查詢功能時

  使用全表掃描的例子 

  SQL> explain plan for select * from dual;
Query Plan
SELECT STATEMENT[CHOOSE] Cost=
TABLE ACCESS FULL DUAL

  ) 通過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=
TABLE ACCESS BY ROWID DEPT [ANALYZED]

  )索引掃描(Index Scan或index lookup)

  我們先通過index查找到數據對應的rowid值(對於非唯一索引可能返回多個rowid值)然後根據rowid直接從表中得到具體的數據這種查找方式稱為索引掃描或索引查找(index lookup)一個rowid唯一的表示一行數據該行對應的數據塊是通過一次i/o得到的在此情況下該次i/o只會讀取一個數據庫塊

  在索引中除了存儲每個索引的值外索引還存儲具有此值的行對應的ROWID值索引掃描可以由步組成() 掃描索引得到對應的rowid值 () 通過找到的rowid從表中讀出具體的數據每步都是單獨的一次I/O但是對於索引由於經常使用絕大多數都已經CACHE到內存中所以第步的I/O經常是邏輯I/O即數據可以從內存中得到但是對於第步來說如果表比較大則其數據不可能全在內存中所以其I/O很有可能是物理I/O這是一個機械操作相對邏輯I/O來說是極其費時間的所以如果多大表進行索引掃描取出的數據如果大於總量的% %使用索引掃描會效率下降很多如下列所示 

  SQL> explain plan for select empno ename from emp where empno=;
Query Plan
SELECT STATEMENT [CHOOSE] Cost=
TABLE ACCESS BY ROWID EMP [ANALYZED]
INDEX UNIQUE SCAN EMP_I

  但是如果查詢的數據能全在索引中找到就可以避免進行第步操作避免了不必要的I/O此時即使通過索引掃描取出的數據比較多效率還是很高的

  SQL> explain plan for select empno from emp where empno=; 只查詢empno列值
Query Plan
SELECT STATEMENT [CHOOSE] Cost=
INDEX UNIQUE SCAN EMP_I

  進一步講如果sql語句中對索引列進行排序因為索引已經預先排序好了所以在執行計劃中不需要再對索引列進行排序

  SQL> explain plan for select empno ename from emp
where empno > order by empno;
Query Plan
SELECT STATEMENT[CHOOSE] Cost=
TABLE ACCESS BY ROWID EMP [ANALYZED]
INDEX RANGE SCAN EMP_I [ANALYZED]

  從這個例子中可以看到因為索引是已經排序了的所以將按照索引的順序查詢出符合條件的行因此避免了進一步排序操作

  根據索引的類型與where限制條件的不同種類型的索引掃描

  索引唯一掃描(index unique scan)

  索引范圍掃描(index range scan)

  索引全掃描(index full scan)

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

  () 索引唯一掃描(index unique scan)

  通過唯一索引查找一個數值經常返回單個ROWID如果存在UNIQUE 或PRIMARY KEY 約束(它保證了語句只存取單行)的話Oracle經常實現唯一性掃描

  使用唯一性約束的例子

  SQL> explain plan for
select empnoename from emp where empno=;
Query Plan
SELECT STATEMENT [CHOOSE] Cost=
TABLE ACCESS BY ROWID EMP [ANALYZED]
INDEX UNIQUE SCAN EMP_I

  () 索引范圍掃描(index range scan)

  使用一個索引存取多行數據在唯一索引上使用索引范圍掃描的典型情況下是在謂詞(where限制條件)中使用了范圍操作符(如><<>>=<=between)

  使用索引范圍掃描的例子

  SQL> explain plan for select empnoename from emp
where empno > order by empno;
Query Plan
SELECT STATEMENT[CHOOSE] Cost=
TABLE ACCESS BY ROWID EMP [ANALYZED]
INDEX RANGE SCAN EMP_I [ANALYZED]

  在非唯一索引上謂詞col = 可能返回多行數據所以在非唯一索引上都使用索引范圍掃描

  使用index rang scan的種情況

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

  (b) 在組合索引上只使用部分列進行查詢導致查詢出多行

  (c) 對非唯一索引列上進行的任何查詢

  () 索引全掃描(index full scan)

  與全表掃描對應也有相應的全索引掃描而且此時查詢出的數據都必須從索引中可以直接得到

  全索引掃描的例子

  An Index full scan will not perform single block i/os and so it may prove to be inefficient
eg
Index BE_IX is a concatenated index on big_emp (empno ename)
SQL> explain plan for select empno ename from big_emp order by empnoename;
Query Plan
SELECT STATEMENT[CHOOSE] Cost=
INDEX FULL SCAN BE_IX [ANALYZED]

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

  掃描索引中的所有的數據塊與 index full scan很類似但是一個顯著的區別就是它不對查詢出的數據進行排序即數據不是以排序順序被返回在這種存取方法中可以使用多塊讀功能也可以使用並行讀入以便獲得最大吞吐量與縮短執行時間

  索引快速掃描的例子

  BE_IX索引是一個多列索引 

  big_emp (empnoename)
SQL> explain plan for select empnoename from big_emp;
Query Plan
SELECT STATEMENT[CHOOSE] Cost=
INDEX FAST FULL SCAN BE_IX [ANALYZED]

  只選擇多列索引的第

  SQL> explain plan for select ename from big_emp;
Query Plan
SELECT STATEMENT[CHOOSE] Cost=
INDEX FAST FULL SCAN BE_IX [ANALYZED]


From:http://tw.wingwit.com/Article/program/Oracle/201311/17452.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.