數據庫掃描方式解析

1) 全表掃描(Full Table Scans, FTS)
爲實現全表掃描,Oracle讀取表中全部的行,並檢查每一行是否知足語句的WHERE限制條件。Oracle順序地讀取分配給表的每一個數據塊,直到讀到表的最高水線處(high water mark, HWM,標識表的最後一個數據塊)。一個多塊讀操做可使一次I/O能讀取多塊數據塊(db_block_multiblock_read_count參數設定),而不是隻讀取一個數據塊,這極大的減小了I/O總次數,提升了系統的吞吐量,因此利用多塊讀的方法能夠十分高效地實現全表掃描, 並且只有在全表掃描的狀況下才能使用多塊讀操做。在這種訪問模式下,每一個數據塊只被讀一次。因爲HWM標識最後一塊被讀入的數據,而delete操做不影響HWM值,因此一個表的全部數據被delete後,其全表掃描的時間不會有改善,通常咱們須要使用truncate命令來使HWM值歸爲0。幸運的是oracle 10G後,能夠人工收縮HWM的值。
由FTS模式讀入的數據被放到高速緩存的Least Recently Used (LRU)列表的尾部,這樣可使其快速交換出內存,從而不使內存重要的數據被交換出內存。
使用FTS的前提條件:在較大的表上不建議使用全表掃描,除非取出數據的比較多,超過總量的5% -- 10%,或你想使用並行查詢功能時。
使用全表掃描的例子:
~~~~~~~~~~~~~~~~~~~~~~~~
SQL> explain plan for select * from dual;
Query Plan
-----------------------------------------
SELECT STATEMENT [CHOOSE] Cost=
TABLE ACCESS FULL DUAL
2) 經過ROWID的表存取(Table Access by ROWID或rowid lookup)
行的ROWID指出了該行所在的數據文件、數據塊以及行在該塊中的位置,因此經過ROWID來存取數據能夠快速定位到目標數據上,是Oracle存取單行數據的最快方法。
爲了經過ROWID存取表,Oracle 首先要獲取被選擇行的ROWID,或者從語句的WHERE子句中獲得,或者經過表的一個或多個索引的索引掃描獲得。Oracle而後以獲得的ROWID爲依據定位每一個被選擇的行。
這種存取方法不會用到多塊讀操做,一次I/O只能讀取一個數據塊。咱們會常常在執行計劃中看到該存取方法,如經過索引查詢數據。
使用ROWID存取的方法:
SQL> explain plan for select * from dept where rowid = 'AAAAyGAADAAAAATAAF';
Query Plan
------------------------------------
SELECT STATEMENT [CHOOSE] Cost=1
TABLE ACCESS BY ROWID DEPT [ANALYZED]
3)索引掃描(Index Scan或index lookup)
咱們先經過index查找到數據對應的rowid值(對於非惟一索引可能返回多個rowid值),而後根據rowid直接從表中獲得具體的數據,這種查找方式稱爲索引掃描或索引查找(index lookup)。一個rowid惟一的表示一行數據,該行對應的數據塊是經過一次i/o獲得的,在此狀況下該次i/o只會讀取一個數據庫塊。 23
在索引中,除了存儲每一個索引的值外,索引還存儲具備此值的行對應的ROWID值。索引掃描能夠由2步組成:(1) 掃描索引獲得對應的rowid值。 (2) 經過找到的rowid從表中讀出具體的數據。 每步都是單獨的一次I/O,可是對於索引,因爲常常使用,絕大多數都已經CACHE到內存中,因此第1步的I/O常常是邏輯I/O,即數據能夠從內存中獲得。可是對於第2步來講,若是表比較大,則其數據不可能全在內存中,因此其I/O頗有多是物理I/O,這是一個機械操做,相對邏輯I/O來講,是極其費時間的。因此若是多大表進行索引掃描,取出的數據若是大於總量的5% -- 10%,使用索引掃描會效率降低不少。 以下列所示: SQL> explain plan for select empno, ename from emp where empno=10; Query Plan ------------------------------------ SELECT STATEMENT [CHOOSE] Cost=1 TABLE ACCESS BY ROWID EMP [ANALYZED] INDEX UNIQUE SCAN EMP_I1 注意TABLE ACCESS BY ROWID EMP部分,這代表這不是經過FTS存取路徑訪問數據,而是經過rowid lookup存取路徑訪問數據的。在此例中,所須要的rowid是因爲在索引查找empno列的值獲得的,這種方式是INDEX UNIQUE SCAN查找,後面給予介紹,EMP_I1爲使用的進行索引查找的索引名字。
相關文章
相關標籤/搜索