IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    unused column 和 drop column操作实质

    luda发表于 2016-05-18 09:15:56
    love 0

    unused column和drop column的操作从本质上讲是不一样的,unused是通过变更数据字典的信息让sql无法访问到column,而drop是直接在物理数据层做了变动。这里的操作后台跟踪可以用event 10046去验证,这里不做描述.

    下面通过实验的方式验证unused和drop column的操作对比情况:

    1.创建测试表

    SQL> grant dba to luda;
    
    Grant succeeded.
    
    SQL> conn luda/luda
    Connected.
    
    
    SQL> create table luda_t1 as  select * from dba_objects;
    
    Table created.
    
    SQL> set timing on
    SQL> set serverout on
    SQL> exec showspace('LUDA_T1','LUDA')
    Total Blocks............................768
    Total Bytes.............................6291456
    Unused Blocks...........................53
    Unused Bytes............................434176
    Last Used Ext FileId....................4
    Last Used Ext BlockId...................2953
    Last Used Block.........................75
    *************************************************
    The segment is analyzed
    0% -- 25% free space blocks.............0
    0% -- 25% free space bytes..............0
    25% -- 50% free space blocks............0
    25% -- 50% free space bytes.............0
    50% -- 75% free space blocks............0
    50% -- 75% free space bytes.............0
    75% -- 100% free space blocks...........0
    75% -- 100% free space bytes............0
    Unused Blocks...........................0
    Unused Bytes............................0
    Total Blocks............................695
    Total bytes.............................5693440
    
    PL/SQL procedure successfully completed.
    
    Elapsed: 00:00:00.00
    SQL> select b.name,a.value from v$mystat a,v$statname b where a.statistic#=b.statistic# and b.name='redo size';
    
    NAME                                                                  VALUE
    ---------------------------------------------------------------- ----------
    redo size                                                             80916
    
    Elapsed: 00:00:00.01
    SQL> select b.name,a.value from v$mystat a,v$statname b where a.statistic#=b.statistic# and b.name='undo change vector size';
    
    NAME                                                                  VALUE
    ---------------------------------------------------------------- ----------
    undo change vector size                                               21012
    
    Elapsed: 00:00:00.00
    

    2.设置object_name为unused

    SQL> alter table luda_t1 set unused column object_name;
    
    Table altered.
    
    Elapsed: 00:00:00.02
    SQL> exec showspace('LUDA_T1','LUDA')  ---- 对比操作前,可以发现luda_t1表存储信息未有变动
    Total Blocks............................768
    Total Bytes.............................6291456
    Unused Blocks...........................53
    Unused Bytes............................434176
    Last Used Ext FileId....................4
    Last Used Ext BlockId...................2953
    Last Used Block.........................75
    *************************************************
    The segment is analyzed
    0% -- 25% free space blocks.............0
    0% -- 25% free space bytes..............0
    25% -- 50% free space blocks............0
    25% -- 50% free space bytes.............0
    50% -- 75% free space blocks............0
    50% -- 75% free space bytes.............0
    75% -- 100% free space blocks...........0
    75% -- 100% free space bytes............0
    Unused Blocks...........................0
    Unused Bytes............................0
    Total Blocks............................695
    Total bytes.............................5693440
    
    PL/SQL procedure successfully completed.
    
    Elapsed: 00:00:00.01
    SQL> select b.name,a.value from v$mystat a,v$statname b where a.statistic#=b.statistic# and b.name='redo size';
    
    NAME                                                                  VALUE
    ---------------------------------------------------------------- ----------
    redo size                                                             92176
    
    Elapsed: 00:00:00.00
    
    ---产生了少量redo日志
    
    SQL> select b.name,a.value from v$mystat a,v$statname b where a.statistic#=b.statistic# and b.name='undo change vector size';
    
    NAME                                                                  VALUE
    ---------------------------------------------------------------- ----------
    undo change vector size                                               25212
    
    Elapsed: 00:00:00.00
    
    --产生了少量undo
    
    

    3.执行drop unused column

    SQL> alter table luda_t1 drop unused column;
    
    Table altered.
    
    Elapsed: 00:00:00.26
    SQL> exec showspace('LUDA_T1','LUDA') --对比操作前可以发现在freespace层面25%-50%多出了642的block
    Total Blocks............................768
    Total Bytes.............................6291456
    Unused Blocks...........................53
    Unused Bytes............................434176
    Last Used Ext FileId....................4
    Last Used Ext BlockId...................2953
    Last Used Block.........................75
    *************************************************
    The segment is analyzed
    0% -- 25% free space blocks.............0
    0% -- 25% free space bytes..............0
    25% -- 50% free space blocks............642
    25% -- 50% free space bytes.............5259264
    50% -- 75% free space blocks............0
    50% -- 75% free space bytes.............0
    75% -- 100% free space blocks...........0
    75% -- 100% free space bytes............0
    Unused Blocks...........................0
    Unused Bytes............................0
    Total Blocks............................53  --总占用block降低为53个,总块数不变642+53=695
    Total bytes.............................434176
    
    PL/SQL procedure successfully completed.
    
    Elapsed: 00:00:00.00
    SQL>  select b.name,a.value from v$mystat a,v$statname b where a.statistic#=b.statistic# and b.name='redo size';
    
    NAME                                                                  VALUE
    ---------------------------------------------------------------- ----------
    redo size                                                          12393932
    
    --产生大量的redo日志相对比上一次操作的redo量
    Elapsed: 00:00:00.01
    SQL> select b.name,a.value from v$mystat a,v$statname b where a.statistic#=b.statistic# and b.name='undo change vector size';
    
    NAME                                                                  VALUE
    ---------------------------------------------------------------- ----------
    undo change vector size                                             5128064
    --产生大量的undo信息相对比上一次操作的undo量
    Elapsed: 00:00:00.00
    SQL>
    

    4.执行drop column的测试

    SQL> alter table luda_t1 drop column object_type;
    
    Table altered.
    
    Elapsed: 00:00:00.25
    SQL> exec showspace('LUDA_T1','LUDA') -- drop 操作效果与drop unused一致,释放空间,降低高水位
    Total Blocks............................768
    Total Bytes.............................6291456
    Unused Blocks...........................53
    Unused Bytes............................434176
    Last Used Ext FileId....................4
    Last Used Ext BlockId...................2953
    Last Used Block.........................75
    *************************************************
    The segment is analyzed
    0% -- 25% free space blocks.............0
    0% -- 25% free space bytes..............0
    25% -- 50% free space blocks............664
    25% -- 50% free space bytes.............5439488
    50% -- 75% free space blocks............1
    50% -- 75% free space bytes.............8192
    75% -- 100% free space blocks...........0
    75% -- 100% free space bytes............0
    Unused Blocks...........................0
    Unused Bytes............................0
    Total Blocks............................30
    Total bytes.............................245760
    
    PL/SQL procedure successfully completed.
    
    Elapsed: 00:00:00.01
    SQL>
    SQL> select b.name,a.value from v$mystat a,v$statname b where a.statistic#=b.statistic# and b.name='redo size';
    
    NAME                                                                  VALUE
    ---------------------------------------------------------------- ----------
    redo size                                                          23902388
    --产生大量的redo日志相对比上一次操作的redo量
    Elapsed: 00:00:00.01
    SQL> select b.name,a.value from v$mystat a,v$statname b where a.statistic#=b.statistic# and b.name='undo change vector size';
    --产生大量的undo信息相对比上一次操作的undo量
    NAME                                                                  VALUE
    ---------------------------------------------------------------- ----------
    undo change vector size                                             9439452
    
    Elapsed: 00:00:00.00
    SQL>
    

    这里验几个情况:

    1.unused column只产生少量的redo和undo,真实在表存储部分并未做变动,高水位线没有变动.真实数据部分并未被oracle处理,而根据trace信息可以发现unused column是在数据字典层面做的变动,对被unused操作的字段打上对于的flag.

    2.drop unused column 操作会对被标记为unused flag的数据进行rewrite(trace可以发现)并释放空间,降低高水位,同时产生大量的redo和undo.

    3.drop column操作会对整个字段物理数据部分直接进行删除(bbed可以发现),并更新table entries.同时降低高水位产生大量的redo和undo.相当于一次数据重组.

    以下的set unused 以及drop column的trace结果图作为参考:

    unused_column

    drop_column



沪ICP备19023445号-2号
友情链接