oracle delete block,Oracle delete和truncate对高水位(HWM)的影响详细解析

在讨论高水位之前需要明确一下oracle的逻辑存储的概念:Block、extent、segment、tablespace

block:块的概念,他是oracle最小的一个存储单元,一般为8K,也是一次io的最基本操作单位。

extent:区的概念,他是由一组连续的block组成的,他是oracle空间分配的基本单位。

segment:段的概念,是有一系列extent组成的,一般说你创建一个对象时,会分配一个段给这个对象,所以我们都会抽象一个表或者一个索引为一个表段或者索引段。

tablespace:包含段,区及块,表空间的数据物理上存储在数据文件里。

oracle段上的HWM是一个标记,标记已经有多少没有使用的数据库分配给这个segment。原则上HWM智慧增加,不会缩小,即使将表的数据全部删除,HWM还是原来的值。truncate命令,会重置HWM为0.

1、讲完了oracle的逻辑存储的概念,接下来我们来模拟创建一张表,并且不插入数据,看看他分配了多少个数据块。

SQL> create table tt(id number);

Table created.

SQL> select segment_name,segment_type,blocks from user_segments where segment_name = 'TT';

no rows selected

我们惊奇的发现在user_segments视图里面是查不到这张表的,这里就引出了11GR2版本的延迟段创建,官方的解释如下:

The initial segment creation for nonpartitioned tables and indexes can be delayed until data is first inserted into an object.

因为很多数据库都有存在空表的情况,较多的空表会占用大量的磁盘空间,所谓延迟段创建,顾名思义就是在创建一张新空表的时候,ORACLE默认不会为这张空表分配段(SEGMENTS),也就是不会为这张空表分配空间,这样就避免了空表占用空间的情况

2、然后我们向这张TT表里插入10000条数据

declare

i number;

begin

for i in 1..10000 loop

insert into tt values(i);

end loop;

commit;

end;

/

select owner,segment_name,segment_type,blocks from dba_segments where segment_name = 'TT';

OWNER SEGMENT_NAME SEGMENT_TYPE BLOCKS

------- ------------- ------------- ------

SCOTT TT TABLE 128

此时TT占用了数据库128个block了,还记得一般插入大量数据的时候,需要收集统计信息的事儿吗?

SQL> exec dbms_stats.gather_table_stats('scott','tt');

PL/SQL procedure successfully completed.

select owner,segment_name,segment_type,blocks from dba_segments where segment_name = 'TT';

OWNER SEGMENT_NAME SEGMENT_TYPE BLOCKS

------- ------------- ------------- ------

SCOTT TT TABLE 128

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 60 0

我们可以看到现在user_tables里面显示了,这个表现在已经使用了60个block,可是我们之前已经分配了128个block,可是这里面的empty_block可是为0啊,这又是为什么呢?

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 60 68

这里需要解释的就是analyze table ** compute statistics也是一种收集统计信息的方式,后来出现了dbms_stats包逐渐取代了analyze的地位。但是有些操作只有analyze只能做,比如刚才的操作。

通过收集统计信息,可以看到empty_block为68个,与60一起正好128吧,跟之前的查询结果相匹配。

3、delete数据的时候,看看是不是会降低高水位

SQL> delete from tt;

10000 rows deleted.

SQL> commit;

Commit complete.

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 60 68

SQL> select owner,segment_name,segment_type,blocks from user_segments where segment_name = 'TT';

OWNER SEGMENT_NAME SEGMENT_TYPE BLOCKS

------- ------------- ------------- ------

SCOTT TT TABLE 128

SQL> analyze table tt compute statistics;

Table analyzed.

SQL> select owner,segment_name,segment_type,blocks from dba_segments where segment_name = 'TT';

OWNER SEGMENT_NAME SEGMENT_TYPE BLOCKS

------- ------------- ------------- ------

SCOTT TT TABLE 128

SQL> select table_name,num_rows,blocks,empty_blocks from user_tables where table_name = 'TT';

TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS

------------------------------ ---------- ---------- ------------

TT 0 60 68

我们发现delete根本不会降低高水位(HWM)

4、验证truncate表,是否会降低高水位

SQL> truncate table tt;

Table truncated.

SQL> select table_name,num_rows,blocks,empty_blocks from user_tables where table_name = 'TT';

TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS

------------------------------ ---------- ---------- ------------

TT 0 60 68

SQL> select segment_name,segment_type,blocks from user_segments where segment_name = 'TT';

SEGMENT_NAME SEGMENT_TYPE BLOCKS

--------------- ------------------ ----------

TT TABLE 128

我们发现段的信息也是没有改变的,那么我们收集一下统计信息来看看

SQL> exec dbms_stats.gather_table_stats('scott','tt');

PL/SQL procedure successfully completed.

SQL> select segment_name,segment_type,blocks from user_segments where segment_name = 'TT';

SEGMENT_NAME SEGMENT_TYPE BLOCKS

--------------- ------------------ ----------

TT TABLE 128

SQL> select table_name,num_rows,blocks,empty_blocks from user_tables where table_name = 'TT';

TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS

------------------------------ ---------- ---------- ------------

TT 0 0 68

段的信息已经改变了,但是empty_block并没有改变,还是需要我们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 0 0 128

我们现在可以看到empty_block是128个。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值