1、什么是水线(High Water Mark)?数据库
全部的oracle段(segments,在此,为了理解方便,建议把segment做为表的一个同义词) 都有一个在段内容纳数据的上限,咱们把这个上限称为"high water mark"或HWM。这个HWM是一个标记,用来讲明已经有多少没有使用的数据块分配给这个segment。HWM一般增加的幅度为一次5个数据块,原则上HWM只会增大,不会缩小,即便将表中的数据所有删除,HWM仍是为原值,因为这个特色,使HWM很象一个水库的历史最高水位,这也就是HWM的原始含义,固然不能说一个水库没水了,就说该水库的历史最高水位为0。可是若是咱们在表上使用了truncate命令,则该表的HWM会被从新置为0。oracle
2、HWM数据库的操做有以下影响:app
a) 全表扫描一般要读出直到HWM标记的全部的属于该表数据库块,即便该表中没有任何数据。post
b) 即便HWM如下有空闲的数据库块,键入在插入数据时使用了append关键字,则在插入时使用HWM以上的数据块,此时HWM会自动增大。性能
3、如何知道一个表的HWM?spa
a) 首先对表进行分析:blog
ANALYZE TABLE ESTIMATE/COMPUTE STATISTICS;索引
b) SELECT blocks, empty_blocks, num_rowsit
FROM user_tablestable
WHERE table_name = ;
说明:
BLOCKS 列表明该表中曾经使用过得数据库块的数目,即水线。
EMPTY_BLOCKS 表明分配给该表,可是在水线以上的数据库块,即历来没有使用的数据块。
让咱们以一个有28672行的BIG_EMP1表为例进行说明:
1) SQL> SELECT segment_name, segment_type, blocks
FROM dba_segments
WHERE segment_name='BIG_EMP1';
SEGMENT_NAME SEGMENT_TYPE BLOCKS
----------------- -------------- ---------
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_blocks
FROM user_tables
WHERE table_name='BIG_EMP1';
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
---------- -------- ------- -------------
BIG_EMP1 28672 700 323
1 row selected.
注意:
BLOCKS + EMPTY_BLOCKS (700+323=1023)比DBA_SEGMENTS.BLOCKS少1个数据库块,这是由于有一个数据库块被保留用做segment header。DBA_SEGMENTS.BLOCKS 表示分配给这个表的全部的数据库块的数目。USER_TABLES.BLOCKS表示已经使用过的数据库块的数目。
4) SQL> SELECT COUNT (DISTINCT
DBMS_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_blocks
FROM user_tables
WHERE table_name='BIG_EMP1';
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
--------- -------- ------- ----------
BIG_EMP1 0 700 323
1 row selected.
9) SQL> SELECT COUNT (DISTINCT
DBMS_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 processed.
11) SQL> ANALYZE TABLE big_emp1 ESTIMATE STATISTICS;
Statement processed.
12) SQL> SELECT table_name,num_rows,blocks,empty_blocks
2> FROM user_tables
3> 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,blocks
FROM dba_segments
WHERE segment_name='BIG_EMP1';
SEGMENT_NAME SEGMENT_TYPE BLOCKS
------------ ------------- ------
BIG_EMP1 TABLE 512
1 row selected.
注意:
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语句来删除表,特别是那种数据量有可能很大的临时存储表。
在手动段空间管理(Manual Segment Space Management)中,段中只有一个HWM,可是在Oracle9iRelease1才添加的自动段空间管理(Automatic Segment Space Management)中,又有了一个低HWM的概念出来。为何有了HWM还又有一个低HWM呢,这个是由于自动段空间管理的特性形成的。在手段段空间管理中,当数据插入之后,若是是插入到新的数据块中,数据块就会被自动格式化等待数据访问。而在自动段空间管理中,数据插入到新的数据块之后,数据块并无被格式化,而是在第一次在第一次访问这个数据块的时候才格式化这个块。因此咱们又须要一条水位线,用来标示已经被格式化的块。这条水位线就叫作低HWM。通常来讲,低HWM确定是低于等于HWM的。
5、修正ORACLE表的高水位线
在ORACLE中,执行对表的删除操做不会下降该表的高水位线。而全表扫描将始终读取一个段(extent)中全部低于高水位线标记的块。若是在执行删除操做后不下降高水位线标记,则将致使查询语句的性能低下。下面的方法均可以下降高水位线标记。
1.执行表重建指令 alter table table_name move;
(在线转移表空间ALTER TABLE 。。。 MOVE TABLESPACE 。。。ALTER TABLE 。。。 MOVE 后面不跟参数也行,不跟参数表仍是在原来的表空间,move后记住重建索引。若是之后还要继续向这个表增长数据,没有必要move,只是释放出来的空间,只能这个表用,其余的表或者segment没法使用该空间)
2.执行alter table table_name shrink space; 注意,此命令为Oracle 10g新增功能,再执行该指令以前必须容许行移动alter table table_name enable row movement;
3.复制要保留的数据到临时表t,drop原表,而后rename临时表t为原表
4.emp/imp
5.alter table table_name deallocate unused
6.尽可能truncate吧