zoukankan      html  css  js  c++  java
  • Shrink space合并表的碎片

    一般表里有碎片我们都采用alter table table_name move tablespace_name,或者exp,drop table table_name,imp的2种方式10G给我们其他的方法.下面我来试一吧
     

    C:/Documents and Settings/Administrator>sqlplus greatfinish/finish
    SQL*Plus: Release 10.2.0.1.0 - Production on 星期一 7月 3 23:34:22 2006
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.

    连接到:
    Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
    With the Partitioning, OLAP and Data Mining options
    greatfinish@TEST> drop table t;
    表已删除。
    --创建测试表
    greatfinish@TEST> create table t as
      2  select rownum id,
      3  dbms_random.string('a', round(dbms_random.value(0,10))) col1,
      4  trunc(sysdate) - dbms_random.value(1, 365*2) col2
      5  from dual connect by rownum<=10000;
    表已创建。
    greatfinish@TEST> exec show_space('T');
    Unformatted Blocks .....................               0
    FS1 Blocks (0-25)  .....................               0
    FS2 Blocks (25-50) .....................               0
    FS3 Blocks (50-75) .....................               0
    FS4 Blocks (75-100).....................               0
    Full Blocks        .....................              32
    Total Blocks............................              40
    Total Bytes.............................         327,680
    Total MBytes............................               0
    Unused Blocks...........................               3
    Unused Bytes............................          24,576
    Last Used Ext FileId....................               4
    Last Used Ext BlockId...................           1,993
    Last Used Block.........................               5
    PL/SQL 过程已成功完成。
    --构造碎片
    greatfinish@TEST> delete from t where mod (id,3)=1;
    已删除3334行。
    提交完成。
    --发现碎片
    greatfinish@TEST> exec show_space('T');
    Unformatted Blocks .....................               0
    FS1 Blocks (0-25)  .....................               0
    FS2 Blocks (25-50) .....................              31
    FS3 Blocks (50-75) .....................               0
    FS4 Blocks (75-100).....................               0
    Full Blocks        .....................               1
    Total Blocks............................              40
    Total Bytes.............................         327,680
    Total MBytes............................               0
    Unused Blocks...........................               3
    Unused Bytes............................          24,576
    Last Used Ext FileId....................               4
    Last Used Ext BlockId...................           1,993
    Last Used Block.........................               5
    PL/SQL 过程已成功完成。
    --9i和之前版本的方法
    greatfinish@TEST> alter table t move;
    表已更改。
    --效果是明显的
    greatfinish@TEST> exec show_space('T');
    Unformatted Blocks .....................               0
    FS1 Blocks (0-25)  .....................               0
    FS2 Blocks (25-50) .....................               0
    FS3 Blocks (50-75) .....................               0
    FS4 Blocks (75-100).....................               0
    Full Blocks        .....................              22
    Total Blocks............................              32
    Total Bytes.............................         262,144
    Total MBytes............................               0
    Unused Blocks...........................               6
    Unused Bytes............................          49,152
    Last Used Ext FileId....................               4
    Last Used Ext BlockId...................           2,025
    Last Used Block.........................               2
    PL/SQL 过程已成功完成。
    greatfinish@TEST> drop table t;
    表已删除。
    greatfinish@TEST> create table t as
      2  select rownum id,
      3  dbms_random.string('a', round(dbms_random.value(0,10))) col1,
      4  trunc(sysdate) - dbms_random.value(1, 365*2) col2
      5  from dual connect by rownum<=10000;
    表已创建。
    greatfinish@TEST> exec show_space('T');
    Unformatted Blocks .....................               0
    FS1 Blocks (0-25)  .....................               0
    FS2 Blocks (25-50) .....................               0
    FS3 Blocks (50-75) .....................               0
    FS4 Blocks (75-100).....................               0
    Full Blocks        .....................              32
    Total Blocks............................              40
    Total Bytes.............................         327,680
    Total MBytes............................               0
    Unused Blocks...........................               3
    Unused Bytes............................          24,576
    Last Used Ext FileId....................               4
    Last Used Ext BlockId...................           1,993
    Last Used Block.........................               5
    PL/SQL 过程已成功完成。
    greatfinish@TEST> delete from t where mod (id,3)=1;
    已删除3334行。
    提交完成。
    greatfinish@TEST> exec show_space('T');
    Unformatted Blocks .....................               0
    FS1 Blocks (0-25)  .....................               0
    FS2 Blocks (25-50) .....................              31
    FS3 Blocks (50-75) .....................               1
    FS4 Blocks (75-100).....................               0
    Full Blocks        .....................               0
    Total Blocks............................              40
    Total Bytes.............................         327,680
    Total MBytes............................               0
    Unused Blocks...........................               3
    Unused Bytes............................          24,576
    Last Used Ext FileId....................               4
    Last Used Ext BlockId...................           1,993
    Last Used Block.........................               5
    PL/SQL 过程已成功完成。
    --10G的方法使用alter table table_name shrink space compact cascade
    greatfinish@TEST> alter table t enable row movement;
    表已更改。
    greatfinish@TEST> alter table t shrink space compact cascade;
    表已更改。
    --效果并不明显
    greatfinish@TEST> exec show_space('T');
    Unformatted Blocks .....................               0
    FS1 Blocks (0-25)  .....................               1
    FS2 Blocks (25-50) .....................               2
    FS3 Blocks (50-75) .....................               0
    FS4 Blocks (75-100).....................              12
    Full Blocks        .....................              17
    Total Blocks............................              40
    Total Bytes.............................         327,680
    Total MBytes............................               0
    Unused Blocks...........................               3
    Unused Bytes............................          24,576
    Last Used Ext FileId....................               4
    Last Used Ext BlockId...................           1,993
    Last Used Block.........................               5
    PL/SQL 过程已成功完成。
    greatfinish@TEST> select block_num,count(*) from
      2  (select dbms_rowid.rowid_block_number(rowid) block_num from t)
      3  group by block_num;
     BLOCK_NUM   COUNT(*)
    ---------- ----------
          1956        352
          1957        352
          1958        351
          1959        346
          1960        351
          1961        349
          1962        349
          1963        350
          1964        351
          1965        352
          1966        353
          1967        354
          1968        350
          1970        347
          1971        348
          1972        353
          1973        348
          1974        288
          1975        212
          1976        210
    已选择20行。
     
    结论说明alter table table_name shrink space compact cascade只合并了部分extents,并没有真正意义上的把数据进行整理.效果没有imp,exp和move好.以后还是用之前的两种来做比较好
     
     

    Oracle 10g

    语法:

    alter table <table_name> shrink space [ <null> | compact | cascade ];

    alter table <table_name> shrink space compcat;

    收缩表,但会保持 high water mark; (这怎么理解?相当于没回缩?)

    alter table <table_name> shrink space;

    收缩表,降低 high water mark;

    alter table <table_name> shrink space cascade;

    收缩表,降低 high water mark,并且相关索引也要收缩一下下。


    shrink space compcat;

     

     方法一:
    Export/Truncate/Import
    方法二:
    alter table table_name move; alter index index_name rebuild;
    这两种方法,哪种更好?我个人觉得方法二更方便。


    如果方便的話,就用第二种。個人一直用的第二种方式!
    前面提到oracle在10g已有專用的命令來做此動作了,如下:
    alter table table_name shrink space;
    後面還有兩個參數:cascade,compact;
    compact:加此參數是爲了黨系統負載比較大時,做此動作可以減小性能影響。在負載比較輕時,在作一次alter table table_name shrink space;就可以了。
    cascade:加上此參數會及聯shrink table上的索引,也相當如rebuild index; 也就相當於你上面在9i裏處理此問題的第二种方式了!

    所以第二种方式是完全可行的,只是要關注做此動作時對性能的影響。一般在系統負載比較輕時做此動作。另rebuild online時,會lock table。此時會影響系統dml操作,因此可以在語句后加online來降低影響,但會增加rebuil時間。總計,均衡當前狀況,來採取最合理的方式!

    我发现一个问题:
    如果 执行  ALTER TABLE xxx MOVE;  后 还没有来的及执行  ALTER INDEX xxx REBUILD;  
    就有人对 该表进行了查询或更新,
    那么就会报错;
    有没有办法在ALTER TABLE xxx MOVE的时候,该表还能正常被使用,这样就不用担心用在执行上面那个批量整理脚本的时候,数据库一些表访问会报错;


    因爲alter table ... move,會使得此表上的索引失效,此時,會使得利用索引訪問此表的sql語句報錯。因此,此動作一般是不會經常做的,也沒這個必要,也不會寫在腳本裏自動執行,還是在系統負載較輕時,手動維護比較好!
    另做此動作后,注意重新分析下此表及對應索引!

    补充:ALTER TABLE xxx MOVE将导致rowid改变,而索引是根据rowid来访问的,所以会出错。

    1:普通表

    shrink必须开启行迁移功能。

    alter table table_name enable row movement ;

    保持HWM
    alter table table_name shrink space compact;

    回缩表与HWM
    alter table table_name shrink space;

    回缩表与相关索引
    alter table table_name shrink space cascade;

    回缩索引
    alter index index_name shrink space;

    Sql脚本

    select'alter table '||table_name||' enable row movement;'||chr(10)||'alter table '||table_name||' shrink space;'||chr(10)fromuser_tables;

    select'alter index '||index_name||' shrink space;'||chr(10)fromuser_indexes;

     

    2分区表的处理

    进行shrink space时 发生ORA-10631错误.shrink space有一些限制.

    在表上建有函数索引(包括全文索引)会失败。

     

    sql脚本

    select 'alter table '||segment_name||' modify subpartition '||partition_name||' shrink space;'||chr(10) from user_segments where segment_type='TABLE SUBPARTITION'

    脚本

    执行方法cmd

            C:"cd到放置两个文件的文件夹

            Sqlplus username/password@oracle_sid

            Sql>@sp.sql

     

    @@sp.sql

     

    set heading off

    set feedback off

    set term off

    set page off

    set trimspool on

    spool a.log

    @a.sql

    spool off

    @@a.log /*慎重,估计好执行时间再执行,也可以手动执行脚本*/

    Exit

     

    @@a.sql

     

    select 'alter table '||table_name||' enable row movement;'||chr(10)||'alter table '||table_name||' shrink space;'||chr(10) from user_tables where table_name ;

    select 'alter index '||index_name||' shrink space;'||chr(10) from user_indexes where uniqueness='NONUNIQUE' ;

    select 'alter table '||segment_name||' modify subpartition '||partition_name||' shrink space;'||chr(10) from user_segments where segment_type='TABLE SUBPARTITION' ';

    相当于把块中数据打结实了。没有变动hwm。
  • 相关阅读:
    【看完想不会都难的系列教程】- (3) JQuery+JQueryUI+Jsplumb 实现拖拽模块,流程图风格
    数据库~大叔通过脚本生成poco实体
    Git~分支真的很轻
    jenkins~管道Pipeline里使用公用类库
    docker~run起来之后执行多条命令
    jenkins~管道Pipeline的使用,再见jenkinsUI
    通过数组初始化链表的两种方法:指向指针的引用node *&tail和指向指针的指针(二维指针)node **tail
    NYOJ 16 矩形嵌套(动态规划)
    SPOJ 416
    sqlserver,执行生成脚本时“引发类型为“System.OutOfMemoryException”的异常”(已解决)
  • 原文地址:https://www.cnblogs.com/sopost/p/2190113.html
Copyright © 2011-2022 走看看