高水位線和全表掃描

 高水位線比如水庫中儲水的水位線,用於描述數據庫中段的擴展方式。高水位線對全表掃描方式有着相當重要的影響。當使用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



3、總結
  一、高水線直接決定了全表掃描所須要的I/O開銷
  二、delete操做不會下降高水位線,高水位線之下的全部塊依然被掃描
  三、使用truncate 會重置高水位線到0位
  四、按期使用alter table tab_name shrink space cascade 有效減小該對象上的I/O開銷
  
4、延伸參考
  收縮表段(shrink space) 

  dbms_xplan之display_cursor函數的使用 
  dbms_xplan之display函數的使用 
  執行計劃中各字段各模塊描述 
  Oracle 綁定變量窺探 
  Oracle 自適應共享遊標  
  Oracle ROWID 
相關文章
相關標籤/搜索