全表掃描(Full Table Scans, FTS)
全表掃描是指Oracle在訪問目標表里的數據時,會從該表所占用的第一個區(EXTENT)的第一個塊(BLOCK)開始掃描,一直掃描到該表的高水位線(HWM,High Water Mark),Oracle會對這期間讀到的所有數據施加目標SQL的where條件中指定的過濾條件,最后只返回那些滿足過濾條件的數據。
不是說全表掃描不好,事實上Oracle在做全表掃描操作時會使用多塊讀,ORACLE采用一次讀入多個數據塊 (database block)的方式優化全表掃描,而不是只讀取一個數據塊,這極大的減少了I/O總次數,提高了系統的吞吐量,所以利用多塊讀的方法可以十分高效地實現全表掃描。這在目標表的數據量不大時執行效率是非常高的,但全表掃描最大的問題就在於走全表掃描的目標SQL的執行時間會不穩定、不可控,這個執行時間一定會隨着目標表數據量的遞增而遞增。因為隨着目標表數據量的遞增,它的高水位線會一直不斷往上漲,所以全表掃描該表時所需要讀取的數據塊的數量也會不斷增加,這意味着全表掃描該表時所需要耗費的I/O資源會隨之不斷增加,當然完成對該表的全表掃描操作所需要耗費的時間也會隨之增加。
在Oracle中,如果對目標表不停地插入數據,當分配給該表的現有空間不足時高水位線就會向上移動,但如果你用DELETE語句從該表刪除數據, 則高水位線並不會隨之往下移動(這在某種程度上契合了"高水位線"的定義,就好比水庫的水位,當水庫漲水時,水位會往上移,當水庫放水后,曾經的最高水位 的痕跡還是會清晰可見)。高水位線的這種特性所帶來的副作用是,即使使用DELETE語句刪光了目標表中的所有數據,高水位線還是會在原來的位置,這意味着全表掃描該表時Oracle還是需要掃描該表高水位線下的所有數據塊,所以此時對該表的全表掃描操作所耗費的時間與之前相比並不會有明顯的改觀。
使用FTS的前提條件:在較大的表上不建議使用全表掃描,除非取出數據的比較多,超過總量的5% -- 10%,或你想使用並行查詢功能時。
例子
以scott的emp表測試

SYS@PDBORCL> alter system flush shared_pool; 系統已更改。 SYS@PDBORCL> alter system flush buffer_cache; 系統已更改。 SYS@PDBORCL> conn scott/tiger@pdborcl Connected. 會話已更改。 SCOTT@PDBORCL> set autotrace traceonly SCOTT@PDBORCL> select * from emp; 已選擇 14 行。 執行計划 ---------------------------------------------------------- Plan hash value: 3956160932 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 14 | 532 | 3 (0)| 00:00:01 | | 1 | TABLE ACCESS FULL| EMP | 14 | 532 | 3 (0)| 00:00:01 | -------------------------------------------------------------------------- 統計信息 ---------------------------------------------------------- 66 recursive calls 0 db block gets 98 consistent gets 13 physical reads 0 redo size 1647 bytes sent via SQL*Net to client 544 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 8 sorts (memory) 0 sorts (disk) 14 rows processed SCOTT@PDBORCL> select * from emp; 已選擇 14 行。 執行計划 ---------------------------------------------------------- Plan hash value: 3956160932 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 14 | 532 | 3 (0)| 00:00:01 | | 1 | TABLE ACCESS FULL| EMP | 14 | 532 | 3 (0)| 00:00:01 | -------------------------------------------------------------------------- 統計信息 ---------------------------------------------------------- 0 recursive calls 0 db block gets 8 consistent gets 0 physical reads 0 redo size 1647 bytes sent via SQL*Net to client 544 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 14 rows processed SCOTT@PDBORCL>
從查詢計划我們可以看到所采用的查詢方式是“TABLE ACCESS FULL”,
再次執行