Oracle:是否可以计算table中数据实际使用的存储大小?
Oracle: is it possible to calculate actual storage size used by the data in a table?
我希望能够报告 table 中的数据所使用的实际存储量,这样我就可以删除 n。行数据(作为数据删除工作的一部分),然后我可以重新分析 table 存储量以计算已通过数据删除释放的实际存储量。
我正在使用以下查询,但我意识到这可能会将 分配的 存储 space 返回给各个 table 段,而不是数据消耗的实际存储space:
SELECT
OWNER "SCHEMA"
,SEGMENT_NAME
,SUM(BYTES) "TOTAL BYTES"
,SUM(BYTES/1024) "TOTAL KB (BINARY)"
,SUM((BYTES/1024)/1024) "TOTAL MB (BINARY)"
,ROUND(SUM(((BYTES/1024)/1024)/1024),6) "TOTAL GB (BINARY)"
FROM dba_segments
WHERE
SEGMENT_TYPE = 'TABLE'
GROUP BY
OWNER
,SEGMENT_NAME
ORDER BY
OWNER
,ROUND (SUM(((BYTES/1024)/1024)/1024),6) desc
Oracle Database Concepts 文档确实很有用,但是通读了其他一些可用于各种静态数据字典视图的文档后,我并不能马上明白 where/what 是最好的基础进行我需要的计算。
例如,如果我从 DBA_TABLES 视图中的 'BLOCKS' 字段中获取统计数据,并将其乘以我们分配的块大小(即 8 字节),就是给我分配的或 table?
的实际数据量
您可能想要基于 dbms_space.space_usage
procedure 的内容。这将告诉您有多少块是 0-25% 满、25-50% 满、50-75% 满、75-100% 满以及完全满。我在下面的脚本中使用了中点估计——如果你想确定你将通过删除大量数据。您还需要 运行 对任何索引、物化视图等执行相同的过程,这些操作会受到从 table.
中删除数据的影响。
drop table foo;
/
create table foo (
col1 number
);
insert into foo
select level
from dual
connect by level <= 10000;
declare
l_unformatted_blocks integer;
l_unformatted_bytes integer;
l_fs1_blocks integer;
l_fs1_bytes integer;
l_fs2_blocks integer;
l_fs2_bytes integer;
l_fs3_blocks integer;
l_fs3_bytes integer;
l_fs4_blocks integer;
l_fs4_bytes integer;
l_full_blocks integer;
l_full_bytes integer;
l_partition_name varchar2(30) := null;
l_segment_size integer;
begin
select sum(bytes)
into l_segment_size
from user_segments
where segment_name = 'FOO';
dbms_space.space_usage( user, 'FOO', 'TABLE',
l_unformatted_blocks, l_unformatted_bytes,
l_fs1_blocks, l_fs1_bytes,
l_fs2_blocks, l_fs2_bytes,
l_fs3_blocks, l_fs3_bytes,
l_fs4_blocks, l_fs4_bytes,
l_full_blocks, l_full_bytes,
l_partition_name );
dbms_output.put_line( 'Segment size is ' || l_segment_size ||
' of which roughly ' ||
to_char(
l_full_bytes +
l_fs4_bytes * 0.125 +
l_fs3_bytes * 0.375 +
l_fs2_bytes * 0.625 +
l_fs1_bytes * 0.875
) ||
' bytes used ' ||
to_char(
8 * 1024 *
l_full_blocks +
l_fs4_blocks * 0.125 +
l_fs3_blocks * 0.375 +
l_fs2_blocks * 0.625 +
l_fs1_blocks * 0.875
) ||
' if we use blocks.'
);
end;
/
我希望能够报告 table 中的数据所使用的实际存储量,这样我就可以删除 n。行数据(作为数据删除工作的一部分),然后我可以重新分析 table 存储量以计算已通过数据删除释放的实际存储量。
我正在使用以下查询,但我意识到这可能会将 分配的 存储 space 返回给各个 table 段,而不是数据消耗的实际存储space:
SELECT
OWNER "SCHEMA"
,SEGMENT_NAME
,SUM(BYTES) "TOTAL BYTES"
,SUM(BYTES/1024) "TOTAL KB (BINARY)"
,SUM((BYTES/1024)/1024) "TOTAL MB (BINARY)"
,ROUND(SUM(((BYTES/1024)/1024)/1024),6) "TOTAL GB (BINARY)"
FROM dba_segments
WHERE
SEGMENT_TYPE = 'TABLE'
GROUP BY
OWNER
,SEGMENT_NAME
ORDER BY
OWNER
,ROUND (SUM(((BYTES/1024)/1024)/1024),6) desc
Oracle Database Concepts 文档确实很有用,但是通读了其他一些可用于各种静态数据字典视图的文档后,我并不能马上明白 where/what 是最好的基础进行我需要的计算。
例如,如果我从 DBA_TABLES 视图中的 'BLOCKS' 字段中获取统计数据,并将其乘以我们分配的块大小(即 8 字节),就是给我分配的或 table?
的实际数据量您可能想要基于 dbms_space.space_usage
procedure 的内容。这将告诉您有多少块是 0-25% 满、25-50% 满、50-75% 满、75-100% 满以及完全满。我在下面的脚本中使用了中点估计——如果你想确定你将通过删除大量数据。您还需要 运行 对任何索引、物化视图等执行相同的过程,这些操作会受到从 table.
drop table foo;
/
create table foo (
col1 number
);
insert into foo
select level
from dual
connect by level <= 10000;
declare
l_unformatted_blocks integer;
l_unformatted_bytes integer;
l_fs1_blocks integer;
l_fs1_bytes integer;
l_fs2_blocks integer;
l_fs2_bytes integer;
l_fs3_blocks integer;
l_fs3_bytes integer;
l_fs4_blocks integer;
l_fs4_bytes integer;
l_full_blocks integer;
l_full_bytes integer;
l_partition_name varchar2(30) := null;
l_segment_size integer;
begin
select sum(bytes)
into l_segment_size
from user_segments
where segment_name = 'FOO';
dbms_space.space_usage( user, 'FOO', 'TABLE',
l_unformatted_blocks, l_unformatted_bytes,
l_fs1_blocks, l_fs1_bytes,
l_fs2_blocks, l_fs2_bytes,
l_fs3_blocks, l_fs3_bytes,
l_fs4_blocks, l_fs4_bytes,
l_full_blocks, l_full_bytes,
l_partition_name );
dbms_output.put_line( 'Segment size is ' || l_segment_size ||
' of which roughly ' ||
to_char(
l_full_bytes +
l_fs4_bytes * 0.125 +
l_fs3_bytes * 0.375 +
l_fs2_bytes * 0.625 +
l_fs1_bytes * 0.875
) ||
' bytes used ' ||
to_char(
8 * 1024 *
l_full_blocks +
l_fs4_blocks * 0.125 +
l_fs3_blocks * 0.375 +
l_fs2_blocks * 0.625 +
l_fs1_blocks * 0.875
) ||
' if we use blocks.'
);
end;
/