全表掃瞄和索引掃瞄的區別

2021-12-29 21:52:01 字數 2387 閱讀 1029

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為使用的進行索引查詢的索引名字。

作者「紅豆加奶」

全表掃瞄與索引掃瞄

一,全表掃瞄 全表掃瞄是從讀取資料的同時通過where條件中的查詢條件來過濾來篩選出滿足條件的資料執行過程。其掃瞄的的物件是表中的所有資料塊,包括空資料庫,如果表中的資料大量被刪除,那麼就會存在大量的空資料塊,再次狀態下,大量的空資料塊也被掃瞄。在執行全表掃瞄時,按照順序每次將多個資料塊從磁碟讀取到...

索引 vs 全表掃瞄

之前我們介紹了第乙個檔案格式 檔案格式簡介 在這個檔案格式裡,資料沒有排序,順序儲存,我們只提供了查詢所有資料的介面,當我們想進行值過濾時,比如查詢大於10的資料,需要將所有資料遍歷一遍,如果把這個檔案看做乙個只有一列的表,這種查詢方式就叫全表掃瞄。磁碟的組織結構 碟片 磁軌 扇區。由於碟片是並行操...

mysql 全表掃瞄 mysql的全表掃瞄

在mysql查詢中,如果表沒有索引的話,當查詢執行時,需要從第一行資料到最後一行資料進行全表掃瞄。索引的目的就是輔助查詢能快速定位到目標資料,然後獲取查詢結果。那麼表是否有了索引就一定能加以應用,而不會進行全表掃面了呢?現實肯定不是這樣的 1 全表掃瞄的場景 使用explain分析sql時,當列出執...