第十四章:高水位线


一 、oracle 高水位线详解


1、什么是水线(High Water Mark )?

         全部的 oracle 段(segments,在此,为了理解方便,建议把 segment 做为表的一个同义词) 都有一个在段内容纳数据的上限,咱们把这个上限称为"high water mark"或 HWM。这个 HWM 是一个标记,用来讲明已经有多少没有使用的数据块分配给这个 segment。HWM 一般增加的幅度为一次5个数据块,原则上 HWM 只会增大,不会缩小,即便将表中的数据所有删除,HWM 仍是为原值,因为这个特色,使 HWM 很象一个水库的历史最高水位,这也就是 HWM的原始含义,固然不能说一个水库没水了,就说该水库的历史最高水位为0。可是若是咱们在表上使用了 truncate命令,则该表的 HWM 会被从新置为0.数据库



2、HWM 数据库的操做有以下影响:

a) 全表扫描一般要读出直到 HWM 标记的全部的属于该表数据库块,即便该表中没有任何数据。oracle

b) 即便 HWM 如下有空闲的数据库块,键入在插入数据时使用了 append 关键字,则在插入时使用 HWM 以上的数据块,此时 HWM 会自动增大app


3、如何知道一个表的 HWM?

  • a) 首先对表进行分析:
    ANALYZE TABLE <tablename> ESTIMATE/COMPUTE STATISTICS;b) SELECT blocks, empty_blocks, num_rowsFROM user_tablesWHERE table_name = <tablename>;
    ---说明:BLOCKS 列表明该表中曾经使用过得数据库块的数目,即水线。EMPTY_BLOCKS 表明分配给该表,可是在水线以上的数据库块,即历来没有使用的数据
---让咱们以一个有28672行的 BIG_EMP1表为例进行说明:
1) SQL> SELECT segment_name, segment_type, blocksFROM dba_segmentsWHERE  segment_name='BIG_EMP1';
SEGMENTNAME        SEGMENTTYPE      BLOCK
----------------- -------------- ---------
BIG_EMP1          TABLE             1024
1 row selected.
2) SQL> ANALYZE TABLE big_emp1 ESTIMATE STATISTICS;Statement processed.
3) SQL> SELECT table_name,num_rows,blocks,empty_blocksFROM user_tablesWHERE table_name='BIG_EMP1';
TABLE_NAME  NUM_ROWS BLOCKS  EMPTY_BLOC
---------- -------- ------- -------------
BIG_EMP1      28672   700     323
1 row selected.
---注意:BLOCKS + EMPTY_BLOCKS (700+323=1023)比 DBA_SEGMENTS.BLOCKS 少1个数据库块,这是由于有一个数据库块被保留用做 segment header。DBA_SEGMENTS.BLOCKS 表示分配给这个表的全部的数据库块的数目。USERTABLES.BLOCKS 表示已经使用过的数据库块的数目。
4) SQL> SELECT COUNT (DISTINCTDBMS_ROWID.ROWID_BLOCK_NUMBER(rowid)||DBMS_ROWID.ROWID_RELATIVE_FNO(rowid)) "Used"FROM big_emp1;
Used
----------
700
1 row selected

5) SQL> delete from big_emp1;28672 rows processed.
6) SQL> commit;Statement processed.
7) SQL> ANALYZE TABLE big_emp1 ESTIMATE STATISTICS;Statement processed.
8) SQL> SELECT table_name,num_rows,blocks,empty_blocksFROM user_tablesWHERE table_name='BIG_EMP1';
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
--------- -------- ------- ----------
BIG_EMP1   0       700       323
1 row selected.
9) SQL> SELECT COUNT (DISTINCTDBMS_ROWID.ROWID_BLOCK_NUMBER(rowid)||DBMS_ROWID.ROWID_RELATIVE_FNO(rowid)) "Used"FROM big_emp1;
Used
----------
0
-----这表名没有任何数据库块容纳数据,即表中无数据1 row selected. 
10) SQL> TRUNCATE TABLE big_emp1;
Statement processe

11) SQL> ANALYZE TABLE big_emp1 ESTIMATE STATISTICS;
Statement processed.
12) SQL> SELECT table_name,num_rows,blocks,empty_blocks  FROM user_tables  WHERE table_name='BIG_EMP1';
TABLE_NAME NUM_ROWS BLOCKS    EMPTY_BLOCKS
---------- -------- -------- ------------
BIG_EMP1    0       0         511
1 row selected.
13) SQL> SELECT segment_name,segment_type,blocksFROM dba_segmentsWHERE segment_name='BIG_EMP1';
SEGMENT_NAME SEGMENT_TYPE    BLOCKS
------------ ------------- ------
BIG_EMP1     TABLE         512
1 row selecte


-----TRUNCATE 命令回收了由 delete 命令产生的空闲空间,注意该表分配的空间由原先的1024块降为512块。为了保留由 delete 命令产生的空闲空间,可使用 TRUNCATE TABLE big_emp1 REUSE STORAGE.用此命令后,该表还会是原先的1024












 

4、Oracle 表段中的高水位线 HWM

       在 Oracle 数据的存储中,能够把存储空间想象为一个水库,数据想象为水库中的水。水库中的水的位置有一条线叫作水位线,在 Oracle 中,这条线被称为高水位线(High-warter mark, HWM)。在数据库表刚创建的时候,因为没有任何数据,因此这个时候水位线是空的,也就是说 HWM 为最低值。当插入了数据之后,高水位线就会上涨,可是这里也有一个特性,就是若是你采用 delete 语句删除数据的话,数据虽然被删除了,可是高水位线没有下降,仍是刚刚删除数据之前的那么高的水位线。也就是说:这条水位线在平常的增删操做中只会上涨,不会下跌。性能


       下面咱们来谈一下 Oracle 中 Select 语句的特性。Select 语句会对表中的数据进行一次扫描,可是究竟扫描多少数据存储块呢,这个并非说数据库中有多少数据,Oracle 就扫描这么大的数据块,而是 Oracle 会扫描高水位线如下的数据块。如今来想象一下,若是刚才是一张刚刚创建的空表,你进行了一次 Select 操做,那么因为高水位线 HWM 在最低的0位置上,因此没有数据块须要被扫描,扫描时间会极短。而若是这个时候你首先插入了一千万条数据,而后再用 delete 语句删除这一千万条数据。因为插入了一千万条数据,因此这个时候的高水位线就在一千万条数据这里。后来删除这一千万条数据的时候,因为 delete 语句不影响高水位线,因此高水位线依然在一千万条数据这里。这个时候再一次用 select 语句进行扫描,虽然这个时候表中没有数据,可是因为扫描是按照高水位线来的,因此须要把一千万条数据的存储空间都要扫描一次,也就是说此次扫描所须要的时间和扫描一千万条数据所须要的时间是同样多的。因此有时候有人老是常常说,怎么个人表中没有几条数据,可是仍是这么慢呢,这个时候其实奥秘就是这里的高水位线了。
       那有没有办法让高水位线降低呢,其实有一种比较简单的方法,那就是采用 TRUNCATE 语句进行删除数据。采用TRUNCATE 语句删除一个表的数据的时候,相似于从新创建了表,不只把数据都删除了,还把 HWM 给清空恢复为0。因此若是须要把表清空,在有可能利用 TRUNCATE 语句来删除数据的时候就利用 TRUNCATE 语句来删除表,特别是那种数据量有可能很大的临时存储spa


 
手动段空间管理(Manual Segment Space Management)中,段中只有一个 HWM,可是在 Oracle9iRelease1才添加的自动段空间管理(Automatic Segment Space Management)中,又有了一个低 HWM 的概念出来。为何有了 HWM 还又有一个低 HWM 呢,这个是由于自动段空间管理的特性形成的。在手段段空间管理中,当数据插入之后,若是是插入到新的数据块中,数据块就会被自动格式化等待数据访问。而在自动段空间管理中,数据插入到新的数据块之后,数据块并无被格式化,而是在第一次在第一次访问这个数据块的时候才格式化这个块。因此咱们又须要一条水位线,用来标示已经被格式化的块。这条水位线就叫作低 HWM。通常来讲,低 HWM 确定是低于等于HWM 的。 日志


5、修正 ORACLE 表的高水位线

        在 ORACLE 中,执行对表的删除操做不会下降该表的高水位线。而全表扫描将始终读取一个段(extent)中全部低于高水位线标记的块。若是在执行删除操做后不下降高水位线标记,则将致使查询语句的性能低下。下面的方法均可以下降高水位线标记。code

1.执行表重建指令 alter table table_name move;blog

    (在线转移表空间 ALTER TABLE 。。。 MOVE TABLESPACE 。。。ALTER TABLE 。。。 MOVE 后面不跟参数也行,不跟参数表仍是在原来的表空间,move 后记住重建索引。若是之后还要继续向这个表增长数据,没有必要 move,只是释放出来的空间,只能这个表用,其余的表或者 segment 没法使用该空间)索引


2.执行 alter table table_name shrink space; get

      注意,此命令为 Oracle 10g 新增功能,再执行该指令以前必须容许行移动 alter table table_name enable row movement;

     实质上构造一个新表(在内部表现为一系列的 DML 操做,即将副本插入新位置,删除原来位置的记录)靠近末尾处(右端)数据块中的记录往开始处(左端)的空闲空间处移动(DML 操做),不会引发 DML 触发器当全部可能的移动被完成,高水位线将会往左端移动(DDL 操做)

新的高水位线右边的空闲空间被释放(DDL 操做)
实现前提条件:必须启用行记录转移(enable row movement)仅仅适用于堆表,且位于自动段空间管理的表空间(堆表包括:标准表,分区表,物化视图容器,物化视图日志表)

3.复制要保留的数据到临时表 t,drop 原表,而后 rename 临时表 t 为原表

4.emp/imp

5.alter table table_name deallocate unused
6.尽可能 truncate






=========================================================================================

相关文章
相关标签/搜索