暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle LOB (un) 压缩会影响现有行吗?

ASKTOM 2019-01-10
899

问题描述

嗨,

我有一个关于LOB压缩的问题。我有一个lob安全文件表与clob数据类型。我想压缩这张表。我在文章中读到,如果我用 (低/中/高) 选项压缩lob
只有新记录将压缩,旧数据将保持未压缩,除非我执行在线重新定义。如果我用下面的命令再次解压缩LOB怎么办。压缩后的数据是否会保持不变 (除非我再次重新定义),并且只有新数据才会被解压缩?

下面的示例语法
====================


()

专家解答

根据文档:

COMPRESS compresses all LOBs in the segment and then returns. NOCOMPRESS uncompresses all LOBs in the segment and then returns.


所以当你改变这个属性时,两者都会发生。

首先,让我们创建一个uncompress LOB并将其加载到高度可压缩的数据中:

create table t1 ( 
  x int,
  c clob
) lob (c) store as securefile (
  enable storage in row
  nocompress
);

insert into t1
  select rownum, rpad('b',12000,'b')
  from   dual
  connect by level <= 10000;

commit;

选择segment_name,sum (字节)
来自用户段
其中segment_name = 't1' 或
分段名称 = (
从用户lob中选择分段名称
其中table_name = 't1'
)
按汇总分组 (segment_name );

分段 _ 名称总和 (字节)
SYS_LOB0000172177C00002$$      100859904 
T1                                655360 
                         101515264 

执行显示 _ 空间;

Segment blocks = 12312 bytes = 100859904
已使用的块 = 10000字节 = 81920000
 Expired blocks = 2162 bytes = 17711104
 Unexpired blocks = 0 bytes = 0


当我们压缩球时,会发生什么?

alter table t1 modify
  lob ( c ) ( compress );

选择segment_name,sum (字节)
来自用户段
其中segment_name = 't1' 或
分段名称 = (
从用户lob中选择分段名称
其中table_name = 't1'
)
按汇总分组 (segment_name );

分段 _ 名称总和 (字节)
SYS_LOB0000172177C00002$$      100859904 
T1 2097152
                         102957056 


嗯?片段仍然是相同的大小!没有压缩!

还是他们...太空报告显示了什么?

执行显示 _ 空间;

Segment blocks = 12312 bytes = 100859904
 Used blocks = 0 bytes = 0
 Expired blocks = 2094 bytes = 17154048
 Unexpired blocks = 10000 bytes = 81920000


啊哈!从1,000到zero。我们已经压缩了数据!

如果移动lob,它将创建一个新的段。比以前小得多:

alter table t1 move
  lob ( c ) store as securefile;

选择segment_name,sum (字节)
来自用户段
其中segment_name = 't1' 或
分段名称 = (
从用户lob中选择分段名称
其中table_name = 't1'
)
按汇总分组 (segment_name );

分段 _ 名称总和 (字节)
SYS_LOB0000172177C00002$$         131072 
T1 2097152
                           2228224 

执行显示 _ 空间;

Segment blocks = 16 bytes = 131072
 Used blocks = 0 bytes = 0
 Expired blocks = 5 bytes = 40960
 Unexpired blocks = 0 bytes = 0


现在,如果您解压缩LOB,数据将不适合现有段。所以他们会成长:

更改表t1修改
lob ( c ) ( nocompress );

选择segment_name,sum (字节)
来自用户段
其中segment_name = 't1' 或
分段名称 = (
从用户lob中选择分段名称
其中table_name = 't1'
)
按汇总分组 (segment_name );

分段 _ 名称总和 (字节)
系统 _ lob0000172177c00002 $84017152
T1 2097152
86114304

执行显示 _ 空间;

段块 = 10256字节 = 84017152
已使用的块 = 10000字节 = 81920000
过期块 = 99字节 = 811008
未过期的块 = 0字节 = 0

show_space过程为:

create or replace procedure show_space as
  l_segment_size_blocks number; 
  l_segment_size_bytes number; 
  l_used_blocks number; 
  l_used_bytes number; 
  l_expired_blocks number; 
  l_expired_bytes number; 
  l_unexpired_blocks number; 
  l_unexpired_bytes number; 
  v_segname varchar2(30); 
  
begin 

  select segment_name 
  into   v_segname 
  from   user_lobs 
  where  table_name = 'T1' 
  and    column_name = 'C'; 
 
  dbms_space.space_usage( 
    segment_owner => user, 
    segment_name => v_segname, 
    segment_type => 'LOB', 
    segment_size_blocks => l_segment_size_blocks, 
    segment_size_bytes => l_segment_size_bytes, 
    used_blocks => l_used_blocks, 
    used_bytes => l_used_bytes, 
    expired_blocks => l_expired_blocks, 
    expired_bytes => l_expired_bytes, 
    unexpired_blocks => l_unexpired_blocks, 
    unexpired_bytes => l_unexpired_bytes 
  ); 

  dbms_output.put_line(' Segment blocks = '||l_segment_size_blocks||' bytes = '||l_segment_size_bytes); 
  dbms_output.put_line(' Used blocks = '||l_used_blocks||' bytes = '||l_used_bytes); 
  dbms_output.put_line(' Expired blocks = '||l_expired_blocks||' bytes = '||l_expired_bytes); 
  dbms_output.put_line(' Unexpired blocks = '||l_unexpired_blocks||' bytes = '||l_unexpired_bytes); 

end show_space;
/

文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论