如何确定 Oracle LOB 存储占用空间?

biz*_*lop 5 oracle-11g-r2 storage blob

通过SECUREFILE存储,我可以指定是否需要压缩(及其级别)和重复数据删除,这完全是时间和空间之间的权衡。

时序相当容易分析,但要对特定 LOB 列占用多少空间进行合理准确的测量,最简单的方法是什么?

seh*_*ope 3

您可以通过 获取 BLOB 列的大小(以字节为单位)DBMS_LOB.GETLENGTH(...)

要获取整个表的列的总大小(以字节为单位),SUM如下所示:

SELECT SUM(DBMS_LOB.GETLENGTH(my_blob_column)) as total_bytes
FROM my_table
Run Code Online (Sandbox Code Playgroud)

如果您已将 BLOB 列标记为已进行重复数据删除,则可以运行类似以下内容的命令来获取有关所使用的实际大小(以字节为单位)的统计信息。比较used_bytes启用设置之前/之后的值,这些设置可能会更改 BLOB 列的大小(例如重复数据删除、压缩等)。

declare  
    p_schema_name           varchar(256) DEFAULT 'THE_SCHEMA_NAME';
    p_table_name            varchar(256) DEFAULT 'THE_TABLE_NAME';
    --
    l_segment_name          varchar2(30);
    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;  

begin
    FOR rec IN (select segment_name 
                from dba_lobs 
                where owner = p_schema_name
                  and table_name = p_table_name
                order by 1)
    LOOP
        dbms_output.put_line('Segment Name=' || rec.segment_name);

        dbms_space.space_usage( 
            segment_owner           => p_schema_name,  
            segment_name            => rec.segment_name, 
            segment_type            => 'LOB', 
            partition_name          => NULL, 
            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_size_blocks       => '||  l_segment_size_blocks);
        dbms_output.put_line('  segment_size_bytes        => '||  l_segment_size_bytes);
        dbms_output.put_line('  used_blocks               => '||  l_used_blocks);
        dbms_output.put_line('  used_bytes                => '||  l_used_bytes);
        dbms_output.put_line('  expired_blocks            => '||  l_expired_blocks);
        dbms_output.put_line('  expired_bytes             => '||  l_expired_bytes);
        dbms_output.put_line('  unexpired_blocks          => '||  l_unexpired_blocks);
        dbms_output.put_line('  unexpired_bytes           => '||  l_unexpired_bytes);
    END LOOP;
end;
/
Run Code Online (Sandbox Code Playgroud)

此代码是 Oracle 解释重复数据删除工作原理的帖子中代码的稍微修改版本。原文可在此处获取:http://www.oracle.com/technetwork/articles/sql/11g-securefiles-084075.html