alter table move lob和 alter table shrink space的区别

比较Oracle中的alter table t move和alter table t shrink space
alter table t move和alter table t shrink space都可以用来进行段收缩,降低高水位HWM,
也都可以用来消除行链接(Row Chaining)和行迁移(Row Migration),
但是有如下区别:
1)使用alter table move,会把表格最多收缩到创建表格时的storage子句指定的初始大小,使用alter table shrink space,则不受此限制。
2)使用alter table move之后,索引会无效,需要重建,使用alter table shrink space,则不会使索引无效。
3)只能在表格所在的表空间是自动段空间管理(创建tablespace时指定了SEGMENT SPACE MANAGEMENT AUTO子句)的时候,才能使用alter table shrink space。
4)可以使用alter table shrink space compact来对表格进行碎片整理,而不调整HWM,之后再次调用alter table shrink space来释放空间。
5)可以使用alter table shrink space cascade来同时对索引都进行收缩,这等同于同时执行alter index shrink space。
下面的例子,创建1个表格T,建表格时的storage子句指定表格初始大小为5M,
block大小为8K,因此等同于5* block。
使用alter table move,会把表格最多收缩到初始大小640 block。
使用alter table shrink space,则不受此限制。
tony@ORA11GR2& select * from v$&
------------------------------------------------------------------------------------------------&
Database 11g Enterprise Edition Release 11.2.0.1.0 - Production&
PL/SQL Release 11.2.0.1.0 - Production&
CORE&&& 11.2.0.1.0&&&&& Production&
TNS for 32-bit Windows: Version 11.2.0.1.0 - Production&
NLSRTL Version 11.2.0.1.0 - Production&
tony@ORA11GR2& show parameter db_block_size&
NAME&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& TYPE&&&&&&&&&&&&&&&&&& VALUE&
------------------------------------ ---------------------- ------------------------------&
db_block_size&&&&&&&&&&&&&&&&&&&&&&& integer&&&&&&&&&&&&&&& 8192&
tony@ORA11GR2& column segment_name format a40;&
tony@ORA11GR2& column table_name format a40;&
tony@ORA11GR2& create table t storage (initial 5m) as select * from all_&
Table created.&
tony@ORA11GR2& exec dbms_stats.gather_table_stats(user, 'T');&
PL/SQL procedure successfully completed.&
tony@ORA11GR2& select table_name, blocks, empty_blocks from user_tables where table_name = 'T';&
TABLE_NAME&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& BLOCKS EMPTY_BLOCKS&
---------------------------------------- ---------- ------------&
T&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&820&&&&&&&&&&& 0&
tony@ORA11GR2& select segment_name, extents, blocks, initial_extent from user_segments where segment_name = 'T';&
SEGMENT_NAME&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& EXTENTS&&&& BLOCKS INITIAL_EXTENT&
---------------------------------------- ---------- ---------- --------------&
T&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 7&&&&&&& 896&&&&&&& 5242880&
tony@ORA11GR2& select count(distinct dbms_rowid.rowid_block_number(rowid))&
COUNT(DISTINCTDBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID))&
---------------------------------------------------&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 804&
tony@ORA11GR2& delete from t where rownum & 50000;&
49999 rows deleted.&
tony@ORA11GR2& create index t_idx on t(object_id);&
Index created.&
tony@ORA11GR2&&
Table altered.&
tony@ORA11GR2& column index_name format a40;&
tony@ORA11GR2& select index_name, status from user_indexes where table_name = 'T';&
INDEX_NAME&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& STATUS&
---------------------------------------- ----------------&
T_IDX&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& UNUSABLE&
tony@ORA11GR2& alter index t_&
Index altered.&
tony@ORA11GR2& exec dbms_stats.gather_table_stats(user, 'T');&
PL/SQL procedure successfully completed.&
tony@ORA11GR2& select table_name, blocks, empty_blocks from user_tables where table_name = 'T';&
TABLE_NAME&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& BLOCKS EMPTY_BLOCKS&
---------------------------------------- ---------- ------------&
T&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 86&&&&&&&&&&& 0&
tony@ORA11GR2& select segment_name, extents, blocks, initial_extent from user_segments where segment_name = 'T';&
SEGMENT_NAME&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& EXTENTS&&&& BLOCKS INITIAL_EXTENT&
---------------------------------------- ---------- ---------- --------------&
T&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 5&&&&&&& 640&&&&&&& 5242880&
tony@ORA11GR2& select count(distinct dbms_rowid.rowid_block_number(rowid))&
COUNT(DISTINCTDBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID))&
---------------------------------------------------&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 82&
tony@ORA11GR2& alter table t&
Table altered.&
tony@ORA11GR2& alter &
Table altered.&
tony@ORA11GR2& select index_name, status from user_indexes where table_name = 'T';&
INDEX_NAME&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& STATUS&
---------------------------------------- ----------------&
T_IDX&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& VALID&
tony@ORA11GR2& exec dbms_stats.gather_table_stats(user, 'T');&
PL/SQL procedure successfully completed.&
tony@ORA11GR2& select table_name, blocks, empty_blocks from user_tables where table_name = 'T';&
TABLE_NAME&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& BLOCKS EMPTY_BLOCKS&
---------------------------------------- ---------- ------------&
T&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 86&&&&&&&&&&& 0&
tony@ORA11GR2& select segment_name, extents, blocks, initial_extent from user_segments where segment_name = 'T';&
SEGMENT_NAME&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& EXTENTS&&&& BLOCKS INITIAL_EXTENT&
---------------------------------------- ---------- ---------- --------------&
T&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&1&&&&&&&& 88&&&&&&& 5242880&
tony@ORA11GR2& select count(distinct dbms_rowid.rowid_block_number(rowid))&
COUNT(DISTINCTDBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID))&
---------------------------------------------------&
&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&82&
下面这个例子可以验证alter table t move和alter table t shrink space都可以用来消除行链接(Row Chaining)和行迁移(Row Migration)。
为此需要先建立chained_rows表格。
首先执行$ORACLE_HOME/RDBMS/ADMIN/utlchain.sql脚本建立chained_rows表格,
然后执行analyze table xxx list chained rows [into chained_rows],
如果存在行链接或者行迁移,查询chained_rows就能找到发生了行链接或者行迁移的行。
tony@ORA11GR2&&
Table dropped.&
tony@ORA11GR2& create table t&
& 2& ( x int primary key,&
& 3&&& y varchar2(4000)&
Table created.&
tony@ORA11GR2& insert into t (x,y)&
& 2& select rownum, rpad('*',148,'*')&
& 3&&& from dual&
& 4& connect by level &= 46;&
46 rows created.&
tony@ORA11GR2& update t set y = rpad('*',2000,'*') where x = 1;&
1 row updated. &
tony@ORA11GR2& analyze table&
Table analyzed.&
tony@ORA11GR2& select count(*) from chained_&
& COUNT(*)&
----------&
&&&&&&&& 1&
tony@ORA11GR2& alter table t&
Table altered.&
tony@ORA11GR2& alter &
Table altered.&
tony@ORA11GR2& delete from chained_&
1 row deleted.&
tony@ORA11GR2& analyze table&
Table analyzed.&
tony@ORA11GR2& select count(*) from chained_&
& COUNT(*)&
----------&
&&&&&&&& 0&
tony@ORA11GR2& update t set y = rpad('*',2000,'*') where x = 2;&
1 row updated.&
tony@ORA11GR2& analyze table&
Table analyzed.&
tony@ORA11GR2& select count(*) from chained_&
& COUNT(*)&
----------&
&&&&&&&& 1&
tony@ORA11GR2&&
Table altered.&
tony@ORA11GR2& delete from chained_&
1 row deleted.&
tony@ORA11GR2& analyze table&
Table analyzed.&
tony@ORA11GR2& select count(*) from chained_&
& COUNT(*)&
----------&
&&&&&&&& 0&
摘自 NowOrNever
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'从10g开始,oracle开始提供Shrink的命令,假如我们的表空间中支持自动段空间管理(ASSM),就可以使用这个特性缩小段,即降低HWM。这里需要强调一点,10g的这个新特性,仅对ASSM表空间有效,否则会报 ORA-10635: Invalid segment or tablespace type。
1 创建实验环境
1.1 创建ASSM的表空间
SQL& set serveroutput on
SQL& create tablespace ASSM datafile '/oradata/ltest/assm.dbf' size 10m autoextend on SEGMENT SPACE MANAGEMENT AUTO;
Tablespace created
SQL& select tablespace_name,
& 2&&&&&&&& block_size,
& 3&&&&&&&& extent_management,
& 4&&&&&&&& allocation_type,
& 5&&&&&&&& segment_space_management
& 6&&& from dba_tablespaces
& 7&& where tablespace_name = 'ASSM';
TABLESPACE_NAME BLOCK_SIZE EXTENT_MANAGEMENT ALLOCATION_TYPE SEGMENT_SPACE_MANAGEMENT
--------------- ---------- ----------------- --------------- ------------------------
ASSM&&&&&&&&&&&&& &&&&8192 LOCAL&&&&&&&&& &&&SYSTEM&&& &&&&&&AUTO
SQL& create table my_objects tablespace assm as select * from all_
Table created
SQL& select count(*) from my_
& COUNT(*)
----------
&&&& 49903
2 实验前的信息
SQL& exec show_space('MY_OBJECTS');
Total Blocks& ..........................768
Total Bytes&& ..........................6291456
Total MBytes& ..........................6
Unused Blocks ..........................62
Unused Bytes& ..........................507904
Unused KBytes ..........................496
Last Used Ext FileId....................7
Last Used Ext BlockId...................649
Last Used Block.........................66
The segment is analyzed below
FS1 Blocks (0-25)&& ....................0
FS2 Blocks (25-50)& ....................0
FS3 Blocks (50-75)& ....................0
FS4 Blocks (75-100) ....................0
Unformatted Blocks& ....................0
Full Blocks&&&&&&&& ....................686
PL/SQL procedure successfully completed
3 删除后的信息
然后我们随机地从table MY_OBJECTS中删除一部分数据:
SQL& delete from my_objects where object_name like '%C%';
17674 rows deleted
SQL& delete from my_objects where object_name like '%U%';
4687 rows deleted
SQL& delete from my_objects where object_name like '%A%';
7010 rows deleted
SQL& exec show_space('MY_OBJECTS');
Total Blocks& ..........................768
Total Bytes&& ..........................6291456
Total MBytes& ..........................6
Unused Blocks ..........................62
Unused Bytes& ..........................507904
Unused KBytes ..........................496
Last Used Ext FileId....................7
Last Used Ext BlockId...................649
Last Used Block.........................66
The segment is analyzed below
FS1 Blocks (0-25)&& ....................0
FS2 Blocks (25-50)& ....................212
FS3 Blocks (50-75)& ....................181
FS4 Blocks (75-100) ....................245
Unformatted Blocks& ....................0
Full Blocks&&&&&&&& ....................48
PL/SQL procedure successfully completed
这里,table my_objects的HWM下有706(768 - 62)个block,其中,free space为25-50%的block有205个,free space为50-75%的block有180个,free space为75-100%的block有229个,full space的block只有45个,这种情况下,我们需要对这个table的现有数据行进行重组。
4 shink操作
要使用assm上的shink,首先我们需要使该表支持行移动,可以用这样的命令来完成:
SQL& alter table my_objects
Table altered
现在,就可以来降低my_objects的HWM,回收空间了,使用命令:
SQL& alter table my_
Table altered
SQL& exec show_space('MY_OBJECTS');
Total Blocks& ..........................280
Total Bytes&& ..........................2293760
Total MBytes& ..........................2.1875
Unused Blocks ..........................5
Unused Bytes& ..........................40960
Unused KBytes ..........................40
Last Used Ext FileId....................7
Last Used Ext BlockId...................265
Last Used Block.........................19
The segment is analyzed below
FS1 Blocks (0-25)&& ....................0
FS2 Blocks (25-50)& ....................1
FS3 Blocks (50-75)& ....................1
FS4 Blocks (75-100) ....................0
Unformatted Blocks& ....................0
Full Blocks&&&&&&&& ....................259
PL/SQL procedure successfully completed
在执行玩shrink命令后,此时表my_objects的HWM现在降到了276(280 - 5 + 1)的位置,而且HWM下的block的空间使用状况,full space的block有259个,free space 为25-50% 和50-75% Block只有1个。
5 shrink space原理剖析
5.1 实验环境
SQL& create table TEST_HWM (id int ,name char(2000)) tablespace ASSM;
Table created
SQL& insert into TEST_HWM values (1, 'aa');
1 row inserted
SQL& insert into TEST_HWM values (2, 'bb');
1 row inserted
SQL& insert into TEST_HWM values (3, 'cc');
1 row inserted
SQL& insert into TEST_HWM values (4, 'ds');
1 row inserted
SQL& insert into TEST_HWM values (5, 'dss');
1 row inserted
SQL& insert into TEST_HWM values (6, 'dss');
1 row inserted
SQL& insert into TEST_HWM values (7, 'ess');
1 row inserted
SQL& insert into TEST_HWM values (8, 'es');
1 row inserted
SQL& insert into TEST_HWM values (9, 'es');
1 row inserted
SQL& insert into TEST_HWM values (10, 'es');
1 row inserted
5.2 删除前rowid状态
SQL& select id,
& 2&&&&&&&& name,
& 3&&&&&&&& rowid,
& 4&&&&&&&& dbms_rowid.rowid_object(rowid) object_id,
& 5&&&&&&&& dbms_rowid.rowid_relative_fno(rowid) file_id,
& 6&&&&&&&& dbms_rowid.rowid_block_number(rowid) block_id,
& 7&&&&&&&& dbms_rowid.rowid_row_number(rowid) num
& 8&&& from test_
&&& ID NAME& ROWID&&&&&&&& &&&&&&OBJECT_ID&&& FILE_ID&& BLOCK_ID&&&&&&& NUM
------ ----- ------------------ ---------- ---------- ---------- ----------
&& &&1 aa&& &AAANAqAAHAAAAElAAA&&&& &53290&&&&&&&&& 7&&&&&&& 293&&&&&&&&& 0
&& &&2 bb &&&AAANAqAAHAAAAElAAB&&&&& 53290&&&&&&&&& 7&&&&&&& 293&&&&&&&&& 1
&&&& 3 cc& &&AAANAqAAHAAAAElAAC&&&&& 53290&&&&&&&&& 7&&&&&&& 293&&&&&&&&& 2
&& &&4 ds &&&AAANAqAAHAAAAEmAAA&&&&& 53290&&&&&&&&& 7&&&&&&& 294&&&&&&&&& 0
&& &&5 dss &&AAANAqAAHAAAAEmAAB&&&&& 53290&&&&&&&&& 7&&&&&&& 294&&& &&&&&&1
&& &&6 dss &&AAANAqAAHAAAAEmAAC&&&&& 53290&&&&&&&&& 7&&&&&&& 294&&&&&&&&& 2
&& &&7 ess& &AAANAqAAHAAAAEnAAA&&&&& 53290&&&&&&&&& 7&&&&&&& 295&&&&&&&&& 0
&& &&8 es& &&AAANAqAAHAAAAEnAAB&&&&& 53290&&&&&&&&& 7&&&&&&& 295&&&&&&&&& 1
&& &&9 es& &&AAANAqAAHAAAAEnAAC&&&&& 53290&&&&&&&&& 7&&&&&&& 295&&&&&&&&& 2
&& &10 es&& &AAANAqAAHAAAAEoAAA&&&&& 53290&&&&&&&&& 7&&&&&&& 296&&&&&&&&& 0
10 rows selected
5.3 删除后rowid状态
然后从table test_hwm中删除一些数据:
SQL& delete from TEST_HWM where id = 2;
1 row deleted
SQL& delete from TEST_HWM where id = 3;
1 row deleted
SQL& delete from TEST_HWM where id = 4;
1 row deleted
SQL& delete from TEST_HWM where id = 7;
1 row deleted
SQL& delete from TEST_HWM where id = 8;
1 row deleted
SQL& select id,
& 2&&&&&&&& name,
& 3&&&&&&&& rowid,
& 4&&&&&&&& dbms_rowid.rowid_object(rowid) object_id,
& 5&&&&&&&& dbms_rowid.rowid_relative_fno(rowid) file_id,
& 6&&&&&&&& dbms_rowid.rowid_block_number(rowid) block_id,
& 7&&&&&&&& dbms_rowid.rowid_row_number(rowid) num
& 8&&& from test_
&& &ID NAME &ROWID&&&&&&&&&&&&&& OBJECT_ID&&& FILE_ID&& BLOCK_ID&&&&&& &NUM
------ ----- ------------------ ---------- ---------- ---------- ----------
&& &&1 aa&& &AAANAqAAHAAAAElAAA&&&&& 53290&&&&&&&&& 7&&&&&&& 293&&&&&& &&&0
&& &&5 dss& &AAANAqAAHAAAAEmAAB&&&&& 53290&&&&&&&&& 7&&&&&&& 294 &&&&&&&&&1
&& &&6 dss& &AAANAqAAHAAAAEmAAC&&&&& 53290&&&&&&&&& 7&&&&&&& 294&&&&& &&&&2
&& &&9 es&& &AAANAqAAHAAAAEnAAC&&&&& 53290&&&&&&&&& 7&&&&&&& 295&&&&& &&&&2
&& &10 es&& &AAANAqAAHAAAAEoAAA&&&&& 53290&&&&&&&&& 7&&&&&&& 296&&&&& &&&&0
从以上的信息,可知表test_hwm中,剩下的数据是分布在AAAAEl,AAAAEm,AAAAEn,AAAAEo这样四个连续的block中。
SQL& exec show_space('TEST_HWM');
Total Blocks& ..........................8
Total Bytes&& ..........................65536
Total MBytes& ..........................0.0625
Unused Blocks ..........................0
Unused Bytes& ..........................0
Unused KBytes ..........................0
Last Used Ext FileId....................7
Last Used Ext BlockId...................289
Last Used Block.........................8
The segment is analyzed below
FS1 Blocks (0-25)&& ....................0
FS2 Blocks (25-50)& ....................1
FS3 Blocks (50-75)& ....................3
FS4 Blocks (75-100) ....................1
Unformatted Blocks& ....................0
Full Blocks&&&&&&&& ....................0
PL/SQL procedure successfully completed
通过show_space_assm我们可以看到目前这四个block的空间使用状况,AAAAEl,AAAAEn,AAAAEo上各有一行数据,可以猜测free space为50-75%的3个block是这三个block,那么free space为25-50%的1个block就是AAAAEm了,剩下free space为 75-100% 的3个block,是HWM下已格式化的尚未使用的block。
5.4 shrink后rowid状态
SQL& alter table my_objects
Table altered
SQL& alter table my_
Table altered
SQL& select id,
& 2&&&&&&&& name,
& 3&&&&&&&& rowid,
& 4&&&&&&&& dbms_rowid.rowid_object(rowid) object_id,
& 5&&&&&&&& dbms_rowid.rowid_relative_fno(rowid) file_id,
& 6&&&&&&&& dbms_rowid.rowid_block_number(rowid) block_id,
& 7&&&&&&&& dbms_rowid.rowid_row_number(rowid) num
& 8&&& from test_
&& &ID NAME &ROWID&&&&&&&&&&&&&& OBJECT_ID&&& FILE_ID&& BLOCK_ID&&&&&& &NUM
------ ----- ------------------ ---------- ---------- ---------- ----------
&&& &9 es&&& AAANAqAAHAAAAEkAAA&&&&& 53290&&&&&&&&& 7&&&&&&& 292&&&&&&&&& 0
&& &10 es&&& AAANAqAAHAAAAEkAAB& &&&&53290&&&&&&&&& 7&&&&&&& 292&&&&&&&&& 1
&&& &1 aa&&& AAANAqAAHAAAAElAAA&&&&& 53290&&&&&&&&& 7&&&&&&& 293&&&&&&&&& 0
&&& &5 dss&& AAANAqAAHAAAAEmAAB&&&&& 53290&&&&&&&&& 7&&&&&&& 294&&&&&&&&& 1
&&& &6 dss&& AAANAqAAHAAAAEmAAC&&&&& 53290&&&&&&&&& 7&&&&&&& 294&&&&&&&&& 2
当执行了shrink操作后,可以发现shrink操作与move不太一样。在move操作的时候,所有行的rowid都发生了变化,table所位于的block的区域也发生了变化,但是所有行物理存储的顺序都没有发生变化,所以我们得到的结论是,oracle以block为单位,进行了block间的数据copy。而在shrink后,部分行数据的rowid发生了变化,同时,部分行数据的物理存储的顺序也发生了变化,而table所位于的block的区域却没有变化(ID为1,5,6的rowid没有发生变化,ID为9,10两行数据,原来在AAAAEn,AAAAEo上都移到AAAAEk上)。以上说明,shrink只移动了table其中一部分的行数据,来完成释放空间,而且,这个过程是在table当前所使用的block中完成的。
6 shrink的注意点
1. move时产生的日志比shrink时少.参看http://blog.csdn.net/huang_xw/article/details/7016365
2. shrink在移动行数据时,也一起维护了index上相应行的数据rowid的信息,当然shrink过程中用来维护index的成本也会比较高。而表move后index的状态是UNUSABLE的,需要进行rebuild。参见http://blog.csdn.net/huang_xw/article/details/7016415
3. oracle是从后向前移动行数据,那么,shrink的操作就不会像move一样,shrink不需要使用额外的空闲空间。
阅读(...) 评论()Oracle 10g Shrink Table和Shrink Space使用详解
Oracle 10g Shrink Table和Shrink Space使用详解
  Oracle 10g Shrink Table的使用是本文我们主要要介绍的内容,我们知道,如果经常在表上执行DML操作,会造成数据库块中数据分布稀疏,浪费大量空间。同时也会影响全表扫描的性能,因为全表扫描需要访问更多的数据块。从Oracle 10g开始,表可以通过shrink来重组数据使数据分布更紧密,同时降低HWM释放空闲数据块。
  segment shrink分为两个阶段:
  1、数据重组(compact):通过一系列insert、delete操作,将数据尽量排列在段的前面。在这个过程中需要在表上加RX锁,即只在需要移动的行上加锁。由于涉及到rowid的改变,需要enable row movement.同时要disable基于rowid的trigger.这一过程对业务影响比较小。
  2、HWM调整:第二阶段是调整HWM位置,释放空闲数据块。此过程需要在表上加X锁,会造成表上的所有DML语句阻塞。在业务特别繁忙的系统上可能造成比较大的影响。Shrink Space语句两个阶段都执行。Shrink Space compact只执行第一个阶段。
  如果系统业务比较繁忙,可以先执行Shrink Space compact重组数据,然后在业务不忙的时候再执行Shrink Space降低HWM释放空闲数据块。shrink必须开启行迁移功能。
  alter table table_name
  注意:alter table XXX enable row movement语句会造成引用表XXX的对象(如存储过程、包、视图等)变为无效。执行完成后,最好执行一下utlrp.sql来编译无效的对象。
  语法:
  alter&table&&table_name&&shrink&space&[&&null&&|&compact&|&cascade&]; &  alter&table&&table_name&&shrink&space&&
  收缩表,相当于把块中数据打结实了,但会保持
  alter table &tablespace_name& Shrink S
  收缩表,降低
  alter table &tablespace_name& Shrink S
  收缩表,降低 high water mark,并且相关索引也要收缩一下下。
  alter index idxname Shrink S
  回缩索引
  1:普通表
  Sql脚本,改脚本会生成相应的语句
  select'alter&table&'||table_name||'&enable&row&'||chr(10)||'alter&table&'||table_name||'&shrink&'||chr(10)from&user_ &  select'alter&index&'||index_name||'&shrink&'||chr(10)from&user_&
  2:分区表的处理
  进行Shrink Space时 发生ORA-10631错误.Shrink Space有一些限制.
  在表上建有函数索引(包括全文索引)会失败。
  Sql脚本,改脚本会生成相应的语句
  select&'alter&table&'||table_name||'&enable&row&'||chr(10)||'alter&table&'||table_name||'&shrink&'||chr(10)&from&user_tables&where&; &  select&'alter&index&'||index_name||'&shrink&'||chr(10)&from&user_indexes&where&uniqueness='NONUNIQUE'&; &  select&'alter&table&'||segment_name||'&modify&subpartition&'||partition_name||'&shrink&'||chr(10)&from&user_segments&where&segment_type='TABLE&SUBPARTITION'&';&
  Shrink的几点问题:
  1.&shrink后index是否需要rebuild:因为shrink的操作也会改变行数据的rowid,那么,如果table上有index时,shrink table后index会不会变为UNUSABLE呢?
  我们来看这样的实验,同样构建my_objects的测试表:
  create&table&my_objects&tablespace&ASSM&as&select&*&from&all_objects&where&rownum&20000; &  create&index&i_my_objects&on&my_objects&(object_id); &  delete&from&my_objects&where&object_name&like&'%C%'; &  delete&from&my_objects&where&object_name&like&'%U%';&
  现在我们来shrink table my_objects:
  SQL&&alter&table&my_objects&enable&row& &  Table&altered &  SQL&&alter&table&my_objects&shrink& &  Table&altered &  SQL&&select&index_name,status&from&user_indexes&where&index_name='I_MY_OBJECTS'; &  INDEX_NAME&STATUS &  ------------------------------&-------- &  I_MY_OBJECTS&VALID&
  我们发现,table my_objects上的index的状态为VALID,估计shrink在移动行数据时,也一起维护了index上相应行的数据rowid的信息。我们认为,这是对于move操作后需要rebuild index的改进。但是如果一个table上的index数量较多,我们知道,维护index的成本是比较高的,shrink过程中用来维护index的成本也会比较高。
  2. shrink时对table的lock
  在对table进行shrink时,会对table进行怎样的锁定呢?当我们对table MY_OBJECTS进行shrink操作时,查询v$locked_objects视图可以发现,table MY_OBJECTS上加了row-X (SX) 的lock:
  SQL&select&OBJECT_ID,&SESSION_ID,ORACLE_USERNAME,LOCKED_MODE&from&v$locked_ &  OBJECT_ID&SESSION_ID&ORACLE_USERNAME&LOCKED_MODE &  ----------&----------&------------------&----------- &  &DLINGER&3 &  SQL&&select&object_id&from&user_objects&where&object_name&=&'MY_OBJECTS'; &  OBJECT_ID &  ---------- &  55422&
  那么,当table在进行shrink时,我们对table是可以进行DML操作的。
  3.shrink对空间的要求
  我们在前面讨论了shrink的数据的移动机制,既然oracle是从后向前移动行数据,那么,shrink的操作就不会像move一样,shrink不需要使用额外的空闲空间。
&&&主编推荐
H3C认证Java认证Oracle认证
基础英语软考英语项目管理英语职场英语
.NETPowerBuilderWeb开发游戏开发Perl
二级模拟试题一级模拟试题一级考试经验四级考试资料
港口与航道工程建设工程法规及相关知识建设工程经济考试大纲矿业工程市政公用工程通信与广电工程
操作系统汇编语言计算机系统结构人工智能数据库系统微机与接口
软件测试软件外包系统分析与建模敏捷开发
法律法规历年试题软考英语网络管理员系统架构设计师信息系统监理师
高级通信工程师考试大纲设备环境综合能力
路由技术网络存储无线网络网络设备
CPMP考试prince2认证项目范围管理项目配置管理项目管理案例项目经理项目干系人管理
Powerpoint教程WPS教程
电子政务客户关系管理首席信息官办公自动化大数据
职称考试题目
就业指导签约违约职业测评
招生信息考研政治
网络安全安全设置工具使用手机安全
3DMax教程Flash教程CorelDraw教程Director教程
Dreamwaver教程HTML教程网站策划网站运营Frontpage教程
生物识别传感器物联网传输层物联网前沿技术物联网案例分析
互联网电信IT业界IT生活
Java核心技术J2ME教程
Linux系统管理Linux编程Linux安全AIX教程
Windows系统管理Windows教程Windows网络管理Windows故障
组织运营财务资本
视频播放文件压缩杀毒软件输入法微博
数据库开发Sybase数据库Informix数据库
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&

我要回帖

更多关于 alter table shrink 的文章

 

随机推荐