Oracle表段中的高水位线HWM : 在Oracle数据的存储中,可以把存储空间幻想为一个水库,数据幻想为水库中的水。 水库中的水的方位有一条线叫作水位线,在Oracle中,这条线被称为高水位线(High-warter mark, HWM)。 在数据库表刚树立的时分,因为没有任何数据,因此这个时分水位线是空的,也就是说HWM为最低值 。当刺进了数据从此,高水位线就会上涨, http://www.fp1111.info/linked/20130305.do; 但是这里也有一个特性,就是如果你选用delete句子删 除数据的话,数据尽管被删去了,但是高水位线却没有降低,还是你方才删去数据从前那么高的水 位。也就是说,这条高水位线在日常的增删操做中只会上涨,不会跌落。HWM通常添加的起伏为一次 5个数据块. Select句子会对表中的数据进行一次扫描,但是终究扫描多少数据存储块呢,这个并非说数据库 中有多少数据,Oracle就扫描这么大的数据块,而是Oracle会扫描高水位线如下的数据块。 了解高水位的效果:了解全表扫描的开支(试验:如果) @@@@@@ 批改ORACLE表的高水位线 ORACLE中,履行对表的删去操做不会降低该表的高水位线。而全表扫描将一直读取一个段(extent) 中一切低于高水位线符号的块。如果在履行删去操做后不降低高水位线符号,则将导致查询句子的 功用低下。rebuild, truncate, shrink,move 等操做会降低高水位。 A、履行表重建指令 alter table table_name move;(把楼移到另外一块地) B、 履行alter table table_name shrink space; 此指令为Oracle 10g新增功用,再履行该指令之 前有必要答应行移动 alter table table_name enable row movement; C、 重建表 仿制要保存的数据到暂时表t,drop原表,而后rename暂时表t为原表 D、 用逻辑导入导出: Emp/Imp E、. Alter table table_name deallocate unused DEALLOCATE UNUSED为开释HWM上面的未运用空间,但是并不会开释HWM下面的自由空间,也不会移动 HWM的方位. F、 引荐运用truncate. @@@@@ ORACLE用HWM来界定一个段中运用的块和未运用的块. 举个好比来讲,当我们创立一个表时,ORACLE就会为这个目标分配一个段.在这个段中,即使我们未插 入任何记载,也至少有一个区被分配,榜首个区的榜首个块就称为段头(SEGMENT HEADE),段头中就储 存了一些信息,其间HWM的信息就存储在此.此刻,因为榜首个区的榜首块用于存储段头的一些信息,虽 然没有存储任何实践的记载,但也算是被运用,此刻HWM是坐落第2个块.当我们不断刺进数据到表后, 第1个块现已放不下后边新刺进的数据,此刻,ORACLE将高水位之上的块用于存储新增数据,一块儿,HWM 自身也向上移.也就是说,当我们不断刺进数据时,HWM会往不断上移,这样,在HWM之下的,就代表运用 过的块,HWM之上的就代表已分配但从未运用过的块. HWM在刺进数据时,当现有空间缺少而进行空间的扩大时会向上移,但删去数据时不会往下移. ORACLE 不会开释空间以供其余目标运用,有一条简略的理由:因为空间是为新刺进的行保存的,并 且要习惯现有行的添加。被占用的最高空间称为最高运用符号 (HWM), @@@ ORACLE的全表扫描是读取高水位符号(HWM)如下的一切块. @@@ 啥样的刺进是在高水位上面进行刺进的?(append操做(不检查高水位线可否有数据,效率高, 不写日志,糟蹋空间)) 当用直接途径刺进行时,即使HWM如下有闲暇的数据库块,键入在刺进数据时运用了append关键词, 则在刺进时运用HWM以上的数据块,此刻HWM会主动增大。 例如,通过直接加载刺进(用 APPEND 提示刺进)或通过 SQL*LOADER 直接途径 数据块直接置于 HWM 之上。它下面的空间就糟蹋掉了。 @@@@ 关联测验: SQL> create table tt (id number);此刻表没有剖析,是原始的数据,即8个数据块。 SQL> select segment_name,segment_type,blocks from dba_segments where segment_nam e='TT'; SEGMENT_NAME -------------------------------------------------------------------------------- SEGMENT_TYPE BLOCK ------------------ ---------- TT TABLE 8(段占用了多少个块) SQL> select table_name,num_rows,blocks,empty_blocks from user_tables where table _name='TT'; TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS ------------------------------ ---------- ---------- ------------ TT declare i number; begin for i in 1..10000 loop insert into tt values(i); end loop; commit; end; / SQL> SELECT segment_name,segment_type,blocks FROM dba_segments WHERE segment_name='TT'; SEGMENT_NAME SEGMENT_TYPE BLOCKS --------------- --------------- ---------- TT TABLE 24 注释:user_dbasegments中的BLOCKS 列表明该表中从前运用过得数据库块的数目 dba_dbasegments中的BLOCKS 列表明段占用多少个块 SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables WHERE table_name='TT'; TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS --------------- ---------- ---------- ------------ TT 此刻表TT 占用的数据库现已经是24个了。 但是user_tables 显现的信息还是为空。 因为没有作计算 剖析。 exec DBMS_STATS.GATHER_TABLE_STATS('SYS','TT');(搜集计算信息) SQL> exec DBMS_STATS.GATHER_TABLE_STATS('SYS','TT');(搜集计算信息) PL/SQL 进程已成功完结。 SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables WHERE table_name='TT'; TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS --------------- ---------- ---------- ------------ TT 10000 20 0 此刻user_tables 现已有了数据,显现的运用了20个数据块。 但是empty_blocks 还是为空。 这里要注重的当地。 这个字段只需运用analyze 搜集计算信息以后才会有数据。 5) 运用analyze 搜集计算信息 SQL> ANALYZE TABLE TT COMPUTE STATISTICS; Table analyzed. SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables WHERE table_name='TT'; TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS --------------- ---------- ---------- ------------ TT 10000 20 3 这个时分高水位在哪里呢?20(20 3=23<24) 这里有显现空的数据库有3个。 注重:20 3=23. 比占用的24个数据块少一个。因为有一个数据库块被保存用做segment header。 delete 数据 看可否会影响他的段巨细 delete from tt; commit SQL> SELECT segment_name,segment_type,blocks FROM dba_segments WHERE segment_name='TT'; SEGMENT_NAME SEGMENT_TYPE BLOCKS --------------- --------------- ---------- TT TABLE 24 SQL>analyze table tt compute statistics;(算出高水位线在那一块) SQL> select table_name,num_rows,blocks,empty_blocks from user_tables where table _name='TT';(blocks为高水位线) TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS ------------------------------ ---------- ---------- ------------ TT 0 20 3 这里我们可以证实了啥:高水位不受delete 影响 SQL>insert into tt select * from tt;(tt现已删去没有数据) SQL> insert into tt select rownum from dba_objects; 已创立50323行。 SQL>analyze table tt compute statistics; SQL> select table_name,num_rows,blocks,empty_blocks from user_tables where table _name='TT';(检查高水位线(blocks))大于20 TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS ------------------------------ ---------- ---------- ------------ TT 50323 79 0 这里我们可以证实了啥:高水位不受commit影响,只需有刺进数据HWM就会添加 @@@@@ 开释高水位(truncate) SQL> truncate table tt; 表被切断。 SQL> ANALYZE TABLE TT COMPUTE STATISTICS; 表已剖析。 SQL> select segment_name,segment_type,blocks from dba_segments where segment_nam e='TT'; SEGMENT_NAME -------------------------------------------------------------------------------- SEGMENT_TYPE BLOCKS ------------------ ---------- TT TABLE 8(又回到原本的8) http://www.fpshamen.com/linked/20130305.do;