数据库

位置:IT落伍者 >> 数据库 >> 浏览文章

Oracle:MOVE与SHRINK命令相比较


发布日期:2021年08月23日
 
Oracle:MOVE与SHRINK命令相比较

MITe命令压缩Oracle块中的记录解决行链接问题并重置表的高水平线

move和shrink命令都会重置表的高水平线那么哪个命令更有效呢?这篇文章讨论使用move和shrink命令重新组织一个表然后比较Oracle块的记录被压缩得怎么样以及行链接解决得怎么样

注意关于表高水平线和重置表高水平线的不同方法的详细讨论不在这篇文章的讨论范围内

下面的步骤简要描述了使用move和shrink命令对TEMP_JP表进行重组时对该表的各种操作在这一系列步骤中出现的一些异常被清晰地标注出来(Move相关的命令是以蓝色表示Shrink相关的命令是以绿色表示)

创建表temp_jp并插入条记录到这个表中

显示在表的Oracle块中的记录分配

奇怪的是插入到每个Oracle块中的记录数不是相同的

索引表temp_jp

检验表和索引的磁盘空间利用情况

默认情况下Oracle为一个表分配一个区间为一个索引分配两个区间

对temp_jp表添加一个第三列来模拟行链接

分析Temp_jp表

从temp_jp表选择行数和链接行数

temp_jp表中几乎所有的记录都是链接的

在模拟行链接之后检查表和索引的磁盘空间利用情况

表temp_jp的磁盘空间使用增加了

删除这个表的所有记录使这个表中每个Oracle块只留一条记录

在删除记录之后展开显示temp_jp表的记录

记录的数目显示了每个Oracle块是一致的因为我们删除了这个表的所有记录这个表中每个Oracle块只留一条记录

分析Temp_jp表

从temp_jp表选择行数和链接行数

检查temp_jp表的索引状态它是VALID

A

对表执行move操作

BA

BB对temp_jp表执行shrink操作

A

在对表执行了move操作之后索引的状态是不可用的

B在对temp_jp表执行了操作之后索引的状态是无效的

显示temp_jp表和它的索引的磁盘空间使用情况

A

在进行move操作之后对表分配了一个区间对索引分配了两个区间

B

在进行shrink操作之后表和索引被分配了每个具有个Oracle块的区间最初分配给索引的两个区间下降为一个

展开显示temp_jp表Oracle块中的记录

A

在temp_jp表中的所有条记录被压缩到一个Oracle块中

B

在temp_jp表中的所有条记录被扩展到个Oracle块中

AA

表分析操作失败错误为ORA

AB

在表上重新建立索引来使其生效

在索引重建操作之后一个Oracle区间被分配给了这个索引

AC

在索引重建之后分析这个表

B

分析这个表

选择temp_jp表的行数和行链接数

A

在对temp_jp表进行move操作之后行链接被解决了链接行数为

B

在对temp_jp表进行shrink操作之后行链接没有解决链接行数为

检验temp_jp表的索引状态是有效的

测试A

move操作怎样影响一个表的Oracle块中行链接和数据的分配

A

drop table temp_jp;

A

create table temp_jp(col number()col varchar()) tablespace users;

A

declare

begin

for i in loop

insert into temp_jp values(iRAMA);

end loop;

commit;

end;

/

A

select dbms_rowidrowid_relative_fno(rowid)

dbms_rowidrowid_block_number(rowid)

count(*)

from temp_jp

group by dbms_rowidrowid_relative_fno(rowid)

dbms_rowidrowid_block_number(rowid)

order by dbms_rowidrowid_relative_fno(rowid)

dbms_rowidrowid_block_number(rowid);

DBMS_ROWIDROWID_RELATIVE_FNO(ROWID) DBMS_ROWIDROWID_BLOCK_NUMBER(ROWID) COUNT(*)

rows selected

A

create index temp_jp_idx on temp_jp(col) tablespace users;

A

select segment_namesegment_typebytes// mgblocksextents

from user_segments where segment_name like TEMP%;

SEGMENT_NAME SEGMENT_TYPE MG BLOCKS EXTENTS

TEMP_JP TABLE

TEMP_JP_IDX INDEX

A

alter table temp_jp add(col varchar() default THIS IS TO TEST THE ROW CHAINING ISSUE

WITH MOVE COMMAND AND HOW THE DATA IS SPREAD BEFORE AND AFTER THE MOVE COMMAND IN EACH BLOCK OF THE TABLE);

A

analyze table temp_jp compute statistics;

A

select table_namenum_rowschain_cnt from user_tables where table_name=TEMP_JP;

TABLE_NAME NUM_ROWS CHAIN_CNT

TEMP_JP

A

select segment_namesegment_typebytes// mgblocksextents

from user_segments where segment_name like TEMP%;

SEGMENT_NAME SEGMENT_TYPE MG BLOCKS EXTENTS

TEMP_JP TABLE

TEMP_JP_IDX INDEX

A

declare

begin

for c in (select DBMS_ROWIDROWID_BLOCK_NUMBER(ROWID) block

max(rowid) max_rowid

from temp_jp group by DBMS_ROWIDROWID_BLOCK_NUMBER(ROWID)) loop

for c in (select rowidDBMS_ROWIDROWID_BLOCK_NUMBER(ROWID) block

from temp_jp

where DBMS_ROWIDROWID_BLOCK_NUMBER(ROWID)=cblock) loop

if ((cblock = cblock) and (crowid <> cmax_rowid)) then

delete from temp_jp where rowid = crowid;

end if;

end loop;

end loop;

commit;

end;

/

A

select dbms_rowidrowid_relative_fno(rowid)

dbms_rowidrowid_block_number(rowid)

count(*)

from temp_jp

group by dbms_rowidrowid_relative_fno(rowid)

dbms_rowidrowid_block_number(rowid)

order by dbms_rowidrowid_relative_fno(rowid)

dbms_rowidrowid_block_number(rowid);

DBMS_ROWIDROWID_RELATIVE_FNO(ROWID) DBMS_ROWIDROWID_BLOCK_NUMBER(ROWID) COUNT(*)

A

analyze table temp_jp compute statistics;

B

select table_namenum_rowschain_cnt from user_tables where table_name=TEMP_JP;

TABLE_NAME NUM_ROWS CHAIN_CNT

TEMP_JP

A

select index_namestatus from user_indexes where table_name=TEMP_JP;

INDEX_NAME STATUS

TEMP_JP_IDX VALID

A

alter table temp_jp move tablespace users;

A

select index_namestatus from user_indexes where table_name=TEMP_JP;

INDEX_NAME STATUS

TEMP_JP_IDX UNUSABLE

A

select segment_namesegment_typebytes// mgblocksextents

from user_segments where segment_name like TEMP%;

SEGMENT_NAME SEGMENT_TYPE MG BLOCKS EXTENTS

TEMP_JP TABLE

TEMP_JP_IDX INDEX

A

select dbms_rowidrowid_relative_fno(rowid)

dbms_rowidrowid_block_number(rowid)

count(*)

from temp_jp

group by dbms_rowidrowid_relative_fno(rowid)

dbms_rowidrowid_block_number(rowid)

order by dbms_rowidrowid_relative_fno(rowid)

dbms_rowidrowid_block_number(rowid);

DBMS_ROWIDROWID_RELATIVE_FNO(ROWID) DBMS_ROWIDROWID_BLOCK_NUMBER(ROWID) COUNT(*)

AA

analyze table temp_jp compute statistics;

analyze table temp_jp compute statistics

*

ERROR at line :

ORA: index GZBGQTTEMP_JP_IDX or partition of such index is in unusable state

AB

alter index TEMP_JP_IDX rebuild online;

AC

analyze table temp_jp compute statistics;

A

select table_namenum_rowschain_cnt from user_tables where table_name=TEMP_JP;

TABLE_NAME NUM_ROWS CHAIN_CNT

TEMP_JP

A

select index_namestatus from user_indexes where table_name=TEMP_JP;

INDEX_NAME STATUS

TEMP_JP_IDX VALID

测试B

shrink操作怎样影响一个表的Oracle块中行链接和数据分配

B

drop table temp_jp;

B

create table temp_jp(col number()col varchar()) tablespace users;

B

declare

begin

foriinloop

insertintotemp_jpvalues(iRAMA);

endloop;

commit;

end;

/

B

select dbms_rowidrowid_relative_fno(rowid)

dbms_rowidrowid_block_number(rowid)

count(*)

from temp_jp

group by dbms_rowidrowid_relative_fno(rowid)

dbms_rowidrowid_block_number(rowid)

order by dbms_rowidrowid_relative_fno(rowid)

dbms_rowidrowid_block_number(rowid);

DBMS_ROWIDROWID_RELATIVE_FNO(ROWID) DBMS_ROWIDROWID_BLOCK_NUMBER(ROWID) COUNT(*)

rows selected

B

create index temp_jp_idx on temp_jp(col) tablespace users;

B

select segment_namesegment_typebytes// mgblocksextents

from user_segments where segment_name like TEMP%;

SEGMENT_NAME SEGMENT_TYPE MG BLOCKS EXTENTS

TEMP_JP TABLE

TEMP_JP_IDX INDEX

B

alter table temp_jp add(col varchar() default THIS IS TO TEST THE ROW CHAINING ISSUE WITH MOVE

COMMAND AND HOW THE DATA IS SPREAD BEFORE AND AFTER THE MOVE COMMAND IN EACH

BLOCK OF THE TABLE);

B

analyze table temp_jp compute statistics;

B

select table_namenum_rowschain_cnt from user_tables where table_name=TEMP_JP;

TABLE_NAME NUM_ROWS CHAIN_CNT

TEMP_JP

B

select segment_namesegment_typebytes// mgblocksextents

from user_segments where segment_name like TEMP%;

SEGMENT_NAME SEGMENT_TYPE MG BLOCKS EXTENTS

TEMP_JP TABLE

TEMP_JP_IDX INDEX

B

declare

begin

for c in (select DBMS_ROWIDROWID_BLOCK_NUMBER(ROWID) block

max(rowid) max_rowid

from temp_jp group by DBMS_ROWIDROWID_BLOCK_NUMBER(ROWID)) loop

for c in (select rowidDBMS_ROWIDROWID_BLOCK_NUMBER(ROWID) block

from temp_jp

where DBMS_ROWIDROWID_BLOCK_NUMBER(ROWID)=cblock) loop

if ((cblock = cblock) and (crowid <> cmax_rowid)) then

delete from temp_jp where rowid = crowid;

end if;

end loop;

end loop;

commit;

end;

/

B

select dbms_rowidrowid_relative_fno(rowid)

dbms_rowidrowid_block_number(rowid)

count(*)

from temp_jp

group by dbms_rowidrowid_relative_fno(rowid)

dbms_rowidrowid_block_number(rowid)

order by dbms_rowidrowid_relative_fno(rowid)

dbms_rowidrowid_block_number(rowid);

DBMS_ROWIDROWID_RELATIVE_FNO(ROWID) DBMS_ROWIDROWID_BLOCK_NUMBER(ROWID) COUNT(*)

rows selected

B

analyze table temp_jp compute statistics;

A

select table_namenum_rowschain_cnt from user_tables where table_name=TEMP_JP;

TABLE_NAME NUM_ROWS CHAIN_CNT

TEMP_JP

B

select index_namestatus from user_indexes where table_name=TEMP_JP;

INDEX_NAME STATUS

TEMP_JP_IDX VALID

BA

alter table temp_jp enable row movement;

BB

alter table temp_jp shrink space cascade;

B

select index_namestatus from user_indexes where table_name=TEMP_JP;

INDEX_NAME STATUS

TEMP_JP_IDX VALID

B

select segment_namesegment_typebytes// mgblocksextents

from user_segments where segment_name like TEMP%;

SEGMENT_NAME SEGMENT_TYPE MG BLOCKS EXTENTS

TEMP_JP TABLE

TEMP_JP_IDX INDEX

B

select dbms_rowidrowid_relative_fno(rowid)

dbms_rowidrowid_block_number(rowid)

count(*)

from temp_jp

group by dbms_rowidrowid_relative_fno(rowid)

dbms_rowidrowid_block_number(rowid)

order by dbms_rowidrowid_relative_fno(rowid)

dbms_rowidrowid_block_number(rowid);

DBMS_ROWIDROWID_RELATIVE_FNO(ROWID) DBMS_ROWIDROWID_BLOCK_NUMBER(ROWID) COUNT(*)

B

analyze table temp_jp compute statistics;

B

select table_namenum_rowschain_cnt from user_tables where table_name=TEMP_JP;

TABLE_NAME NUM_ROWS CHAIN_CNT

TEMP_JP

B

select index_namestatus from user_indexes where table_name=TEMP_JP;

INDEX_NAME STATUS

TEMP_JP_IDX VALID

在对temp_jp表进行move操作之后所有的记录被压缩进一个oracle块中在temp_jp表中的行链接问题被完全解决了

shrink不能完全解决表中行链接问题表中留下的条记录被扩展到这个表的个oracle块中

在上面的比较之后对于一个读取要求较高执行以毫秒来计的应用程序我推荐使用move命令

上一篇:Oracle rac安装过程详解(五)

下一篇:在Linux下装配Oracle