高水位線比如水庫中儲水的水位線,用於描述數據庫中段的擴展方式。高水位線對全表掃描方式有着相當重要的影響。當使用delete 操做
表記錄時,高水位線並不會降低,隨之致使的是全表掃描的實際開銷並無任何減小。本文給出高水位線的描述,如何下降高水位線,以及高水
位線對全表掃描的影響。 sql
1、何謂高水位線
如前所述,相似於水庫中儲水的水位線。只不過在數據庫中用於描述段的擴展方式。
能夠將數據段或索引段等想象爲一個從左到右依次排開的一系列塊。當這些塊中未填充任何數據時,高水位線位於塊的最左端(底端)
隨着記錄的不斷增長,新塊不斷地被填充並使用,高水位線隨之向右移動。高水位線之上爲未格式化的數據塊。
刪除(delete)操做以後,高水位線之下的塊處於空閒狀態,但高水位線並不隨之降低,直到重建,截斷或收縮表段。
全表掃描會掃描高水位線之下的全部塊,包括空閒數據塊(執行了delete操做)。
低高水位線
是在使用ASSM時的一個概念。即便用ASSM時除了高水位線以外,還包括一個低高水位線。低高水位線必定是位於高水位線之下。
當段使用MSSM管理方式時只有一種狀況即只存在一個高水位線。
使用MMSM時,當HWM升高時,Oracle當即格式化全部塊且有效,並能夠安全讀取。僅當第一次使用時完成格式化,便於安全讀取數據。
使用ASSM時,當HWM升高時,Oracle並不會當即格式化全部塊。僅當第一次使用時完成格式化,便於安全讀取數據。
使用低高水位線能夠減小當全面掃描表段時,低高水位線與高水位線之間不安全塊的檢查數量。即低高水位線之下的塊再也不檢查。 數據庫
SQL> create table t -->建立測試表 2 as 3 select rownum as id, 4 round(dbms_random.normal*1000) AS val1, 5 dbms_random.string('p',250) AS pad 6 from dual 7 connect by level <=10000; Table created. SQL> exec dbms_stats.gather_table_stats('SCOTT','T',cascade=>true); -->收集統計信息 SQL> @Tab_Stat -->從dba_tab_statistics中得到表對象的統計信息,此時無empty_blocks的信息 Enter value for input_table_name: t Enter value for input_owner: scott NUM_ROWS BLKS EM_BLKS AVG_SPACE CHAIN_CNT AVG_ROW_LEN AVG_ROWS_PER_BLOCK LST_ANLY STA ---------- ---------- ---------- ---------- ---------- ----------- ------------------ --------- --- 10000 387 0 0 0 259 26 03-NOV-11 NO /**************************************************/ /* Author: Robinson Cheng */ /* Blog: http://blog.csdn.net/robinson_0612 */ /* MSN: robinson_0612@hotmail.com */ /* QQ: 645746311 */ /**************************************************/ SQL> analyze table t compute statistics; -->執行analyze SQL> @Tab_Stat -->此時的empty_blocks值爲125 Enter value for input_table_name: t Enter value for input_owner: scott NUM_ROWS BLKS EM_BLKS AVG_SPACE CHAIN_CNT AVG_ROW_LEN AVG_ROWS_PER_BLOCK LST_ANLY STA ---------- ---------- ---------- ---------- ---------- ----------- ------------------ --------- --- 10000 387 125 920 0 262 26 03-NOV-11 NO SQL> col segment_name format a15 SQL> select segment_name,segment_type,blocks,extents from dba_segments -->查看錶段上的塊的信息 2 where segment_name='T' and owner='SCOTT'; SEGMENT_NAME SEGMENT_TYPE BLOCKS EXTENTS -->此數據字典中記錄的塊數爲512塊(包含了已使用塊與空閒塊) --------------- ------------------ ---------- ---------- T TABLE 512 19 SQL> set autotrace traceonly; -->開啓autotrace SQL> select count(*) from t; -->此時SQL語句的執行計劃爲全表掃描(執行計劃中部分信息被省略) Execution Plan ---------------------------------------------------------- Plan hash value: 2966233522 ------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 86 (0)| 00:00:02 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | TABLE ACCESS FULL| T | 10000 | 86 (0)| 00:00:02 | ------------------------------------------------------------------- Statistics ---------------------------------------------------------- 1 recursive calls 0 db block gets 375 consistent gets -->consistent gets的值爲375 0 physical reads SQL> set autotrace off; SQL> delete from t where rownum<=9900; -->刪除大多數的記錄,刪除後剩餘記錄值爲100 9900 rows deleted. SQL> commit; SQL> exec dbms_stats.gather_table_stats('SCOTT','T',cascade=>true); -->收集統計信息 SQL> analyze table t compute statistics; -->收集統計信息 SQL> @Tab_Stat -->此時對象上的統計信息無任何變化,即高水位線沒有發生任何變化 Enter value for input_table_name: t Enter value for input_owner: scott NUM_ROWS BLKS EM_BLKS AVG_SPACE CHAIN_CNT AVG_ROW_LEN AVG_ROWS_PER_BLOCK LST_ANLY STA ---------- ---------- ---------- ---------- ---------- ----------- ------------------ --------- --- 100 387 125 7921 0 262 0 03-NOV-11 NO SQL> set autotrace traceonly SQL> select count(*) from t; -->SQL的執行計劃中預估的值準確,爲100行 Execution Plan ---------------------------------------------------------- Plan hash value: 2966233522 ------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 86 (0)| 00:00:02 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | TABLE ACCESS FULL| T | 100 | 86 (0)| 00:00:02 | ------------------------------------------------------------------- Statistics ---------------------------------------------------------- 1 recursive calls 0 db block gets 375 consistent gets -->consistent gets的值仍然爲375,並無降低 0 physical reads SQL> set autotrace off; SQL> alter table t enable row movement; -->啓用row movement SQL> alter table t shrink space cascade; --> 實施shrink space SQL> alter table t disable row movement; SQL> exec dbms_stats.gather_table_stats('SCOTT','T'); SQL> analyze table t compute statistics; SQL> @Tab_Stat -->此時對象上的統計信息已發生變化,已使用的塊爲4塊,空閒塊爲4塊 Enter value for input_table_name: t Enter value for input_owner: scott NUM_ROWS BLKS EM_BLKS AVG_SPACE CHAIN_CNT AVG_ROW_LEN AVG_ROWS_PER_BLOCK LST_ANLY STA ---------- ---------- ---------- ---------- ---------- ----------- ------------------ --------- --- 100 4 4 7921 0 259 25 03-NOV-11 NO SQL> set autotrace traceonly SQL> select count(*) from t; Execution Plan ---------------------------------------------------------- Plan hash value: 2966233522 ------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 3 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | TABLE ACCESS FULL| T | 100 | 3 (0)| 00:00:01 | ------------------------------------------------------------------- Statistics ---------------------------------------------------------- 1 recursive calls 0 db block gets 6 consistent gets -->表段收縮以後,consistent gets由375降低爲6 0 physical reads SQL> truncate table t; -->使用表截斷技術(turncate table) Table truncated. SQL> exec dbms_stats.gather_table_stats('SCOTT','T'); -->收集統計信息 PL/SQL procedure successfully completed. SQL> select count(*) from t; -->此時執行計劃中的rows變爲1 Execution Plan ---------------------------------------------------------- Plan hash value: 2966233522 ------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 2 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | TABLE ACCESS FULL| T | 1 | 2 (0)| 00:00:01 | ------------------------------------------------------------------- Statistics ---------------------------------------------------------- 1 recursive calls 0 db block gets 3 consistent gets -->consistent gets的值降爲3 0 physical reads