逻辑存储结构

存储结构

官方文档入口:

  Database Concepts ---> 12 Logical Storage Structures

TABLESPACE(表空间)

1.1 定义

  表空间是一个逻辑概念,物理上对应一个或多个数据文件datafile或临时文件tempfiles,逻辑上表空间是存储段的容器。(段也是逻辑概念,是数据库中的对象如表、索引等)

1.2 类型和管理方式

表空间类型:

  ①PERMANENT            永久表空间

  ②UNDO                        撤销表空间

  ③TEMPORARY            临时表空间

管理方式重点是段的管理方式区的管理方式是在建立表空间时确定的

段管理方式有AUTO和MANUAL两种,区管理方式有本地管理字典管理(已淘汰)两种

1.2.1 查看表空间类型、段和区管理方式

select tablespace_name,contents,segment_space_management,extent_management from dba_tablespaces;

select * from v$tablespace;

1.2.2 查看表空间数据文件)大小、是否自动扩展

col file_name for a45
col tablespace_name for a10
select file_id,file_name,tablespace_name,bytes/1024/1024 M,status,AUTOEXTENSIBLE from dba_data_files order by 1;

1.2.3 查看表空间大小

一个表空间可能对应多个数据文件

select TABLESPACE_NAME,sum(bytes)/1024/1024 M from dba_data_files group by tablespace_name;

1.2.4 查看表空间空闲大小

select tablespace_name,sum(bytes)/1024/1024 M from dba_free_space group by tablespace_name;

1.2.5 可在OEM中查看表空间情况

1.3 基本操作

1.3.1 small表空间扩展

表空间的大小等同它有的数据文件大小之和,默认使用small表空间当发生表空间不足的问题时常用的3个解决办法:

  • 增加原有数据文件大小(resize)
  • 增加一个数据文件(add datafile)
  • 设置表空间自动增长(autoextend)

1.3.1.1 创建small表空间

create tablespace orcl datafile '/u01/app/oracle/oradata/ORCL/prod01.dbf' size 5m;
create table scott.test1 (id number) tablespace orcl;
insert into scott.test1 select empno from scott.emp;
insert into scott.test1 select * from scott.test1;

报错:空间不足

1.3.1.2 resize扩充表空间【第一种方法】
select file_id,file_name,tablespace_name from dba_data_files;

alter database datafile 2 resize 10m;
insert into scott.test1 select * from scott.test1;

继续添加数据,报错

使用第二种方法扩充表空间

1.3.1.3 add datafile扩充表空间【第二种方法】
alter tablespace prod add datafile '/u01/app/oracle/oradata/PROD/prod02.dbf' size 20m;
insert into scott.test1 select * from scott.test1;

继续添加数据,报错

使用第三种方法扩充表空间

1.3.1.4 autoextend on扩充表空间【第三种方法】
alter database datafile 2 autoextend on next 10m maxsize 500m;

select FILE_ID,TABLESPACE_NAME,BYTES/1024/1024 Tsize,AUTOEXTENSIBLE,MAXBYTES/1024/1024 Tmax from dba_data_files;

drop tablespace orcl including contents and datafiles;

1.3.1.5 数据文件移动或改名

可以将一个在线数据文件从一种存储系统移动或改名到另一个存储系统

当一个数据文件正在进行移动的时候,可以执行查询,DML,DDL操作,包括如下:查询语句,创建表和索引,重建索引

注:被移动的数据文件的对象是压缩状态时,压缩状态不变

  在移动数据文件到另一个位置或存储系统时,我们不一定要关闭数据库或者将数据文件置为离线状态

  TO从句只有当是OMF管理时才可以省略通过DB_CREATE_FILE_DEST 参数来设置最新的位置。如果REUSE选项被指定,已存在的文件会被覆盖。如果KEEP语句指定,旧的文件会在移动过程中保留,但是OMF管理的文件不支待keep

  可以使用V$SESSION_LONGOPS视图来显示正在执行的移动操作,移动操作的状态有三种:NORMAL、COPYING、SUCCESS最后又回到NORMAL状态

1.3.2 建立大文件(bigfile)的表空间

  • smallfile,在一个表空间可以建立多个数据文件(默认),不支持 32G 以上
  • bigfile:在一个表空间只能建立一个数据文件 (8k block 时,最大可达 32T),简化对数据文件管理
create tablespace test datafile '/u01/app/oracle/oradata/ORCL/test01.dbf' size 32G;

超出小文件的最大块数,创建bigfile

create bigfile tablespace big_tbs datafile '/u01/app/oracle/oradata/ORCL/bigtbs01.dbf' size 100m;

bigfile表空间下增加一个数据文件会报错

alter tablespace big_tbs add datafile '/u01/app/oracle/oradata/ORCL/bigtbs02.dbf' size 100m;

查看大文件表空间

select name,bigfile from v$tablespace;

1.3.3 建表空间缺省选项dbms_metadata.get_ddl

create tablespace a datafile '/u01/app/oracle/oradata/ORCL/a01.dbf' size 10M;

利用oracle提供的dbms_metadata.get_ddl包看看缺省值都给的是什么

set serveroutput on

declare
 v_sql varchar2(2000);
begin
 select dbms_metadata.get_ddl('TABLESPACE','A') into v_sql FROM 
 dual;
 dbms_output.put_line(v_sql);
end;
/

CREATE TABLESPACE "A" DATAFILE '/u01/app/oracle/oradata/ORCL/a01.dbf' SIZE 10485760
LOGGING ONLINE PERMANENT BLOCKSIZE 8192
EXTENT MANAGEMENT LOCAL AUTOALLOCATE DEFAULT         区本地管理且自动分配空间
NOCOMPRESS SEGMENT SPACE MANAGEMENT AUTO             段自动管理

dbms_metadata.get_ddl也可以查看表,将('TABLE','EMP','SCOTT')替换('TABLESPACE','A')即可

create tablespace b datafile '/u01/app/oracle/oradata/ORCL/b01.dbf' size 10m
extent management local uniform size 128k
segment space management manual;

同上,调dbms_metadata.get_ddl包看Oracle对该语句的ddl操作

declare
 v_sql varchar2(2000);
begin
 select dbms_metadata.get_ddl('TABLESPACE','B') into v_sql FROM 
 dual;
 dbms_output.put_line(v_sql);
end;
/

CREATE TABLESPACE "B" DATAFILE '/u01/app/oracle/oradata/ORCL/b01.dbf' SIZE 10485760
LOGGING ONLINE PERMANENT BLOCKSIZE 8192
EXTENT MANAGEMENT LOCAL UNIFORM SIZE 131072 DEFAULT
NOCOMPRESS SEGMENT SPACE MANAGEMENT MANUAL

区本地管理且统一分配128K,段空间手动管理

如果在建表时使用缺省说明,则该表将服从其表空间的这些定义

1.3.4 删除表空间

表空间的删除和offline

drop tablespace B including contents and datafiles;

contents包括控制文件和数据字典信息,datafiles是物理数据文件

数据库OPEN下不能删除的表空间是:

  • system
  • active undo tablespace
  • default temporary tablespace
  • default tablespace

数据库OPEN下不能offine的表空间是

  • system
  • active undo tablespace
  • default temporary tablespace

1.3.5 查看默认表空间、默认临时表空间

col PROPERTY_NAME for a30
col PROPERTY_VALUE for a60
select PROPERTY_NAME,PROPERTY_VALUE from database_properties where property_name like 'DEFAULT%';

1.3.6 临时表空间

1.3.6.1 用途

用于缓存排序的数据(中间结果)

可以建立多个临时表空间,但默认的临时表空间只能有一个且不能offline和drop

temp表空间是nologing的(不记日志)

select file_id,file_name,tablespace_name,bytes/1024/1024 M,status,AUTOEXTENSIBLE from dba_temp_files;

col name for a60
select file#,name,bytes/1024/1024 M from v$tempfile;

select TABLESPACE_NAME,TABLESPACE_SIZE/1024/1024,ALLOCATED_SPACE/1024/1024,FREE_SPACE/1024/1024 from dba_temp_free_space;

1.3.6.2 基本操作
1.3.6.2.1 建立临时表空间temp2,增加或删除tempfile
create temporary tablespace temp2 tempfile '/u01/app/oracle/oradata/ORCL/temp02.dbf' size 10m;

alter tablespace temp2 add tempfile '/u01/app/oracle/oradata/ORCL/temp03.dbf' size 5m;

select file_id,file_name,tablespace_name from dba_temp_files;

1.3.6.2.2 删除临时表空间temp2里一个tempfile
alter tablespace temp2 drop tempfile '/u01/app/oracle/oradata/ORCL/temp03.dbf';
select file_id,file_name,tablespace_name from dba_temp_files;

1.3.6.2.3 查看默认的临时表空间
select PROPERTY_NAME,PROPERTY_VALUE from database_properties where property_name like 'DEFAULT%';

1.3.6.2.4 切换数据库默认临时表空间
alter database default temporary tablespace temp2;

1.3.6.2.5 指定用户使用临时表空间
alter user scott temporary tablespace temp2;

  注意:某个tempfile坏掉使得default temporary tablespace不能正常工作,数据库不会crash,解决的办法是add一个新的tempfile,然后再drop掉坏的tempfile(default temporary tablespace不能offline,但temporary file可以offline)

1.4 OMF

Oracle Managed Files Oracle管理文件,数据库内部使用标准文件系统接口来创建,删除文件,可以针对以下数据库文件管理:

  • Tablespaces
  • Redo log files
  • Control files
  • Archived logs
  • Block change tracking files
  • Flashback logs
  • RMAN backups

  一个数据库可能有OMF和非OMF的文件。文件所在的操作系统目录是需要预先存在的,Oracle不会创建。例如设置了DB_CREATE_FILE_DESTDATAFILECREATETABLESPACE语句中, 会将数据文件自动放到上面参数设定的目录
注:默认ASM使用OMF管理文件,但是如果我们指定了另外的名称,那么不会受OMF管理

 

SEGMENT(段)

2.1 段的类型和特点

  • 段是逻辑概念,对应数据库中的对象
  • 表空间在逻辑上可以对应多个段,物理上可以对应多个数据文件,一个段比较大时可以跨多个数据文件(表可以跨数据文件)
  • 创建一个表,ORACLE为表创建一个(或多个)段,在一个段中保存该表的所有表数据(表数据不能跨段)
  • 通常段中至少有一个初始区。当这个段数据增加使得区(extent)不够时,将为这个段分配新的后续区(11g段空间延时分配)
  • 段的类型:表段、索引段、undo段、临时段

2.2 表和段的关系

  一般来讲,一个单纯的表就分配一个段,但往往表没那么单纯,比如表上经常会有主键约束,那么就会有索引,索引有索引段,还有分区表,每个分区会有独立的段,再有就是Oracle的大对象,如果你的表里引用blob、clob、那么这个表就又被分出多个段来

select segment_name,segment_type from dba_segments where owner='SCOTT';

2.3 延迟段:段空间延迟分配

  顾名思义, 延迟段就是创建表的时候并不马上建立相应的段

  Oracle11gR2又增加了一个新的初始化参数DEFERRED_SEGMENT_CREATION(仅适用未分区的heap table),此参数默认TRUE,当create table后并不马上分配segment,仅当第一个insert语句后才开始分配segment。这对于应用程序的部署可能有些好处

  也可以使局部设置改变这一功能(覆盖DEFERRED_SEGMENT_CREATION=TRUE),在 create table语句时加上segment creation immediate子句指定

show parameter deferred

2.3.1 创建实验用户demo

grant connect,resource to demo identified by demo;

conn demo/demo
select * from user_segments;

2.3.2 创建表、查看段分配

create table t1 (id number);
select * from user_segments;

2.3.3 插入数据、查看段分配

insert into t1 values(100);
select segment_name,SEGMENT_TYPE,bytes/1024 K,TABLESPACE_NAME from user_segments;

2.4 segment creation immediate

修改为创建表时指定立刻分配段

create table t2 (id number) segment creation immediate;
select segment_name,SEGMENT_TYPE,bytes/1024 K,TABLESPACE_NAME from user_segments;

2.5 unusable索引

  在oracle中使用了额外的特性来节省空间。所有的UNUSABLE index和index partition都不创建segments。例如:如果有一个DEMO表,有三个分区和分别一个本地索引,当执行查询的时候,会看到三个表和三个索引段

  如果将一个分区移动到一个新表空间,会看到三个表段和两个索引段因为unusable的索引段会自动删除

2.6 一表对应多段

2.6.1 关闭延迟段

alter system set deferred_segment_creation=false;
show parameter deferred

2.6.2 创建带有主键约束、lob列的表

create table t3(id number constraint pk_t3 primary key,name clob);
col segment_name for a30
select segment_name,SEGMENT_TYPE,bytes/1024 K,TABLESPACE_NAME from user_segments;

2.6.3 开启延迟段

alter system set deferred_segment_creation=true;
show parameter deferred

2.7 dba_segmentsdba_tables

dba_segments 从空间分配角度来看,显示分配了多少

dba_tables 从空间使用角度来看,显示使用了多少,需要分析表收集统计信息

desc user_segtables;
desc user_tables;

2.7.1 user_segments

col segment_name for a10
select segment_name,BLOCKS from user_segments where segment_name='T1';

8表示分配了8个块

2.7.2 user_tables

直接查看, 没有信息显示

select table_name,blocks,empty_blocks from user_tables where table_name='T1';

分析表收集统计信息,再次查看

analyze table t1 compute statistics;
select table_name,blocks,empty_blocks from user_tables where table_name='T1';

2.8 段管理方式

自动段空间管理和手动段空间管理最大区别在空闲块的管理

2.8.1 自动管理方式ASSM

Auto Segment Space Management简称ASSM

采用位图bitmap管理段的存储空间

  空闲空间在数据库段中可以自动管理。段空闲的或者使用的空间被记录在位图中。利用这个特点,当创建一个本地管理表空间时使用自动的段空间管理

  自动空间管理段有一组位图块(BMBs)描述段中空间使用的数据块。BMB以树状组织。根层包含所有要参照的BMB, 存储在段头。 叶子层代表着段中一组连续数据块的空间信息。最多只能有三层。使用自动空间管理(automatic space management)的好处:

  • 更好的空间利用率,特别是对于行大小变化很大的对象
  • 更好地调整并发访问中的变化
  • 在性能或空间利用率方面更好的多实例行为

  原理:简单说就是每个段的段头都有一组位图(5个位图),位图描述每个块的满度,根据满度的不同将每个块登记到相应的位图上,位图自动跟踪每个块的使用空间(动态),5个位图的满度按如下定义:满度100%、75%、50%、25%和0%,比如块大小为8k,你要插入一行是3k的表行,那么oracle就给你在满度50%的位图上找个登记的可插入的块

  ASSM的前提是EXTENT MANAGEMENT LOCAL,在ORACLE9i以后,缺省状态为自动管理方式

  ASSM废弃pctused属性

2.8.2 手工管理方式MSSM

Manual Segment Space Managementj简称MSSM

采用FREELIST(空闲列表)管理段的存储空间

原理:这是传统的方法,现在仍然在使用,涉及三个概念freelist、pctfree和 pctused

  1. freelist:空闲列表中登记了可以插入数据的可用块,位置在段头,插入表行数据时首先查找该列表
  2. pctfree:用来为一个块保留的空间百分比,以防止在今后的更新操作中增加一列或多列值的长度。达到该值,从freelist清除该块信息
  3. pctused:一个块的使用水位的百分比,这个水位将使该块返回到可用列表中去等待更多的插入操作。达到该值,该块信息登录到freelist

这个参数在ASSM下不使用。ASSM使用位图状态位取代了pctused

 

3 EXTENT(区)

3.1 特点

区是ORACLE进行存储空间分配的基本单位。 一个区是由一系列逻辑上连续的Oracle数据块组成的逻辑存储结构。段中第一个区叫初始区,随后分配的区叫后续区

3.2 管理方式

1)字典管理:在数据字典中管理表空间的区空间分配。Oracle 8i以前只有通过uet$fet$的字典管理

缺点:某些在字典管理方式下的存储分配有时会产生递归操作,并且容易产生碎片,从而影响了系统的性能,现在已经淘汰了

2)本地管理:在每个数据文件中使用位图管理空间的分配。表空间中所有区(extent)的分配信息都保存在该表空间对应的数据文件的头部

每个区的大小:autoallocate 自动调整/uniform size 固定大小

优点:速度快,存储空间的分配和可恢复只是简单地改变数据文件中的位图,而不像字典管理方式还需要修改数据库。无碎片,更易于DBA 维护

3.3 【表和区的关系】

当建立表的时候建立段,然后自动分配相应的extent1个或者多个),亦可以手工提前分配extent(用于需大量插入数据的表)

实验: 查看段的初始区分配情况

create tablespace test datafile '/u01/app/oracle/oradata/ORCL/test01.dbf' size 10M;
create table scott.t1 tablespace test as select * from scott.dept;

col segment_name for a15
select SEGMENT_NAME,FILE_ID,EXTENT_ID,BLOCK_ID,BLOCKS,BYTES/1024 K from dba_extents where segment_name='T1';

col file_name for a50
select file_id,file_name,tablespace_name from dba_data_files;

scott用户插入数据,直到空间不足报错

insert into t1 select * from t1;

查看dba_extents分配情况

select SEGMENT_NAME,FILE_ID,EXTENT_ID,BLOCK_ID,BLOCKS,BYTES/1024 K from dba_extents where segment_name='T1';

添加数据文件

alter tablespace test add datafile '/u01/app/oracle/oradata/ORCL/test02.dbf' size 20M autoextend on;

scott再次插入数据

insert into t1 select * from t1;
commit;

查看dba_extents

查看分配的总块

select sum(blocks) from dba_extents where segment_name='T1';
select blocks from dba_segments where segment_name='T1';

查看使用的总块

analyze table scott.t1 compute statistics;
select table_name,blocks,empty_blocks from dba_tables where table_name='T1';

 

4 BLOCK(数据块)

4.1 OracleBlock的构成

BLOCKOracle进行存储空间IO操作的最小单位。构成上分为block headerfree spacedata数据块头部:

  • ITL:事务槽,可以有多个ITL以支持并发事务,每当一个事务要更新数据块里的数据时,必须先得到一个ITL槽,然后将当前事务ID,事务所用的undo数据块地址,SCN号,当前事务是否提交等信息写到ITL槽里
  • initrans:初始化事务槽的个数,表默认1,index默认为2
  • maxtrans:最大的事务槽个数(默认255
  • ROW DIR:行目录,指向行片段行起始和结束的偏移量

4.2 块空间的管理

空间管理包括在块级别管理空闲空间,伴随着Automatic Segment Space Management,每个块被分为四个部分:FS1(between 0 and 25% of free space),FS2(25% to 50% free),FS3(50% to 75% free) and FS4(75% to 100% free)

根据块中空闲空间的级别,它的状态会自动更新。这样,根据插入行的长度,您可以判断是否可以使用特定的块来满足插入操作。注意,“full”状态意味着块不再可用于插入

4.3 行链接和行迁移

4.3.1 什么是行链接和行迁移

行链接:指一行存储在多个块中的情况,即行链接是跨越多块的行

插入时,一个块存不下,insert到多个块中

行迁移:指一个数据行由于update语句导致当前块被重新定位到另一个块(那里有充足的空间)中,但在原始块中会保留一个指针。原始块中的指针是必需的,因为索引的ROWID项仍然指向原始位置

行迁移是update语句当pctfree空间不足时引起的,它与insert和delete语句无关

  在两种情况下,表中的一行数据可能太大填满了一个数据块。

  第一种情况,在第一次插入数据时,行太大填满了一个数据块。在这种情况下,Oracle以数据块的链形式存储行数据。在行太大的情况下容易出现行链接,例如行包含数据类型为LONG或LONG RAW的列。行链接在这些情况下是不可避免的

  然而在第二种情况下,数据块中原始的行被更新,因此行的长度增加,并且块的空闲空间总是完全被填充。在这种情况下,Oracle移动整行数据到另一个新的数据块,假设整行被填充到了一个新块,数据库保留一个被迁移行指向新块的原始行piece。迁移行的ROWID信息不会改变

4.3.2 如何知道发生了行链接或行迁移

查看dba_tablesAVG_ROW_LEN列和CHAIN_CNT

drop table t1 purge;
create table t1 (c1 varchar2(20));

begin
 for i in 1..1000 loop
 insert into t1 values(null);
 end loop;
end;
/

先分析一下t1表,确定无行迁移

analyze table t1 compute statistics;
select pct_free,pct_used,avg_row_len,chain_cnt,blocks from user_tables where table_name='T1';

select SEGMENT_NAME,FILE_ID,EXTENT_ID,BLOCK_ID,BLOCKS,BYTES/1024 K from dba_extents where segment_name='T1';

填充这些空列,再分析t1,有了行迁移

update t1 set c1='orcl is my name';
commit
analyze table t1 compute statistics;

select pct_free,pct_used,avg_row_len,chain_cnt,blocks from user_tables where table_name='T1';

说明1000行中有840行发生了行迁移

4.3.3 行迁移

@?/rdbms/admin/utlchain.sql
analyze table scott.t1 LIST CHAINED ROWS;
select count(*) from chained_rows;

select table_name, HEAD_ROWID from chained_rows where rownum<=3;

select dbms_rowid.ROWID_RELATIVE_FNO(rowid) fn,dbms_rowid.rowid_block_number(rowid) bn, rowid,c1 from scott.t1 where rowid='AAASEGAAHAAAAGTABQ';

4.3.4 解决行迁移方法

可以根据上例chained_rows表中提供的rowid,将t1表中的那些记录删除,然后在重新插入。这里使用move解决

alter table t1 move;

move表后,再分析t1,行迁移消失

analyze table t1 compute statistics;
select pct_free,pct_used,avg_row_len,chain_cnt,blocks from user_tables where table_name='T1';

4.3.5 行链接

4.3.5.1 创建表、插入普通数据
create table t2 (c1 varchar2(4000),c2 varchar2(4000),c3 varchar2(4000));

begin
 for i in 1..100 loop
 insert into t2 values ('a','b','c');
 end loop;
 commit;
end;
/

select pct_free,avg_row_len,chain_cnt,blocks from user_tables where table_name='T2';

4.3.5.2 插入大于8K
insert into t2 values (lpad('a',4000,'a'),lpad('a',4000,'a'),lpad('a',4000,'a'));
commit;

analyze table t2 compute statistics;
select pct_free,avg_row_len,chain_cnt,blocks from user_tables where table_name='T2';

4.3.5.3 创建非标准块大小表空间16K
show parameter cache
alter system set db_16k_cache_size=16m;
create tablespace tbs16k datafile '/u01/app/oracle/oradata/ORCL/tbs16k01.dbf' size 20M blocksize 16K;

alter table t2 move tablespace tbs16k;
analyze table t2 compute statistics;
select pct_free,avg_row_len,chain_cnt,blocks from user_tables where table_name='T2';

4.4 高水位线HWM

1)什么是高水位线?

高水位线(high-water markHWM

在数据库中,如果把表想象成从左到右依次排开的一系列块,高水位线就是曾经包含了数据的最右边的块。原则上HWM只会增大,即使将表中的数据全部删除,HWM也不会降低

2HWM有利有弊

优点:可以使HWM以下的块重复利用

缺点:使用全表扫描时要读取HWM以下的所有block,耗费更多的IO资源

4.5 如何降低HWM高水位线

多种方法可以降低HWM

  • 移动表
  • 收缩表
  • 导入导出表
  • 在线重定义表

4.5.1 移动表move

move方法,将表从一个表空间移动到另一个表空间(也可以在本表空间内move)。语法:alter table t1 move [tablespace users];

优点:可以清除数据块中的碎片,降低高水位线。适用MSSM和ASSM

缺点:

  • move需要额外(一倍)的空间
  • move过程中会锁表,其他用户不能在该表上做DML或DDL操作
  • move之后,相关索引都不可用了,表上的索引需要重建
create table emp1 as select * from emp;
create index emp1_idx on emp1(ename);
select table_name,index_name,status from user_indexes where table_name='EMP1';

alter table emp1 move;
select table_name,index_name,status from user_indexes where table_name='EMP1';

alter index EMP1_IDX rebuild online;
select table_name,index_name,status from user_indexes where table_name='EMP1';

4.5.2 收缩表shrink

Shrink方法,也叫段重组,表收缩的底层实现的是通过匹配的INSERTDELETE操作

语法:alter table t2 shrink space [cascade][compact];

优点:使用位图管理技术,①降低热块,②更合理的重新利用空闲块

缺点:①要求段管理是ASSM方式,②表上启用row movement

它分两个不同的阶段:压缩阶段和降低HWM阶段

第一阶段:发出alter table t2 shrink space compact;命令,这是压缩阶段。在业务高峰时可以先完成这样步骤

第二阶段:再次alter table t2 shrink space;因压缩阶段工作大部分已完成,将很快进入降低HWM阶段,DML操作会有短哲的锁等待发生

  对于堆表操作,紧缩操作可能会引起ROWID的变化,在进行紧缩之前,必须要开启对应段的行迁移,在段级别行迁移默认是被禁止的。可以在CREATE TABLE or ALTER TABLE命令时使用ENABLE ROW MOVEMENT语句开启

4.5.2.1 创建表、查看信息
create table scott.t3 as select * from dba_objects;

select count(*) from t3;

analyze table t3 compute statistics;
select table_name,blocks,empty_blocks from user_tables where table_name='T3';

Blocks:表示使用过的块,即低于HWM的块数量

empty_blocks:表示extent分配了,但从未使用过的块,即高于HWM的块数量1441+95=1536是这个段分配的块数

select segment_name,blocks from user_segments where segment_name='T3';

4.5.2.2 delete不降低HWM

删除40000

delete from t3 where rownum <=40000;
commit;
analyze table t3 compute statistics;
select table_name,blocks,empty_blocks from user_tables where table_name='T3';

num_rows已经减掉了40000条,但blocks并没有减少,说明HWM没有下降

shrink

4.5.2.3 使能行移动
alter table t3 enable row movement;

4.5.2.4 第一步:压缩阶段HWM不降低
alter table t3 shrink space compact;
analyze table t3 compute statistics for table;
select table_name, blocks, empty_blocks, num_rows from user_tables where table_name='T3';

4.5.2.5 第二步:降低HWM阶段
alter table t3 shrink space;
analyze table t3 compute statistics;
select table_name, blocks, empty_blocks, num_rows from user_tables where table_name='T3';

4.5.2.6 truncate对比
truncate table t3;
analyze table t3 compute statistics;
select table_name, blocks, empty_blocks, num_rows from user_tables where table_name='T3';

posted @ 2021-06-23 11:02  chchcharlie、  阅读(467)  评论(0编辑  收藏  举报