网上对Oracle的高水位讲解很多,这里我自己整理一下,以便后续复习回顾。
1.什么是高水位?(high water mark 简称:HWM)
简单理解就是:高水位好比水库中储水的水位,用于描述数据库中段的扩展方式。高水位对全表扫描方式有着至关重要的影响。当使用DELETE删除表记录时,高水位并不会下降,随之导致的是全表扫描的实际开销并没有任何减少。
例如:
首先新建一张空表,大小占用5K,然后插入1000万条数据,直到表大小变为50G,此时使用DELETE删除所有的数据并且提交,这个时候查询表的大小的时候依然是50G,这就是因为表的高水位没有释放的缘故。而在这时如果使用“SELECT * FROM TABLE_NAME;”语句来查询数据的话,那么查询过程依然会很慢,因为Oracle要执行全表扫描,高水位下所有的块都得去扫描,直到50G的所有块全部扫描完毕。其实这个问题就是由于高水位的缘故。在Oracle中执行delete删除操作不会降低高水位。而执行truncate操作可以降低高水位,通常能把高水位降到0。 所以为了降低高水位,能尽量使用truncate的就不使用delete操作。(视业务规则而定)
2.如何查询高水位
--每次查询各个结果时先分析表 才能得到最新的分析结果
analyze table biu_issuer_info compute statistics;
select num_rows, blocks, empty_blocks, owner
from user_tables
where table_name = 'BIU_ISSUER_INFO'; --注意这里查询一定要用大写
select count(distinct dbms_rowid.rowid_block_number(rowid) ||
dbms_rowid.rowid_relative_fno(rowid)) zs
from BIU_ISSUER_INFO;
--如果实际用的块数比高水位线低很多的话,则调整高水位可显著改善全表扫描效率
alter table BIU_ISSUER_INFO enable row movement;
alter table BIU_ISSUER_INFO shrink space;
3.如何解决高水位
1.能使用truncate的尽量不适用delete操作。
2.新建一个临时表,把数据复制到临时表,然后把源表drop掉,再把临时表重新命名为源表的名字。
3.移动表空间(或者不移动表空间)
4.执行表重建命令:
alter table table_name move;
(在线转移表空间ALTER TABLE 。。。 MOVE TABLESPACE 。。。ALTER TABLE 。。。 MOVE 后面不跟参数也行,不跟参数表还是在原来的表空间,move后记住重建索引。如果以后还要继续向这个表增加数据,没有必要move,只是释放出来的空间,只能这个表用,其他的表或者segment无法 使用该空间)
5.压缩片收缩高水位:
alter table table_name shrink space;
注意,此命令为Oracle 10g新增功能,再执行该指令之前必须允许行移动alter table table_name enable row movement;