当前位置:  开发笔记 > 数据库 > 正文

如何在Oracle中计算表大小

如何解决《如何在Oracle中计算表大小》经验,为你挑选了7个好方法。

习惯了(也可能被宠坏了)MSSQL,我想知道如何在Oracle 10g中获得表大小.我用谷歌搜索了所以我现在意识到我可能没有像sp_spaceused那样简单的选项.我得到的潜在答案仍然是大部分时间过时或不起作用.可能是因为我不是我正在使用的架构上的DBA.

有人会有解决方案和建议吗?



1> WW...:

您可能对此查询感兴趣.它告诉您为每个表分配了多少空间,同时考虑了索引和表中的任何LOB.通常,您有兴趣知道"Purchase Order表占用多少空间,包括任何索引",而不仅仅是表本身.您可以随时深入了解详细信息.请注意,这需要访问DBA_*视图.

COLUMN TABLE_NAME FORMAT A32
COLUMN OBJECT_NAME FORMAT A32
COLUMN OWNER FORMAT A10

SELECT
   owner, 
   table_name, 
   TRUNC(sum(bytes)/1024/1024) Meg,
   ROUND( ratio_to_report( sum(bytes) ) over () * 100) Percent
FROM
(SELECT segment_name table_name, owner, bytes
 FROM dba_segments
 WHERE segment_type IN ('TABLE', 'TABLE PARTITION', 'TABLE SUBPARTITION')
 UNION ALL
 SELECT i.table_name, i.owner, s.bytes
 FROM dba_indexes i, dba_segments s
 WHERE s.segment_name = i.index_name
 AND   s.owner = i.owner
 AND   s.segment_type IN ('INDEX', 'INDEX PARTITION', 'INDEX SUBPARTITION')
 UNION ALL
 SELECT l.table_name, l.owner, s.bytes
 FROM dba_lobs l, dba_segments s
 WHERE s.segment_name = l.segment_name
 AND   s.owner = l.owner
 AND   s.segment_type IN ('LOBSEGMENT', 'LOB PARTITION')
 UNION ALL
 SELECT l.table_name, l.owner, s.bytes
 FROM dba_lobs l, dba_segments s
 WHERE s.segment_name = l.index_name
 AND   s.owner = l.owner
 AND   s.segment_type = 'LOBINDEX')
WHERE owner in UPPER('&owner')
GROUP BY table_name, owner
HAVING SUM(bytes)/1024/1024 > 10  /* Ignore really small tables */
ORDER BY SUM(bytes) desc
;



2> grokster..:
-- Tables + Size MB
select owner, table_name, round((num_rows*avg_row_len)/(1024*1024)) MB 
from all_tables 
where owner not like 'SYS%'  -- Exclude system tables.
and num_rows > 0  -- Ignore empty Tables.
order by MB desc -- Biggest first.
;


--Tables + Rows
select owner, table_name, num_rows
 from all_tables 
where owner not like 'SYS%'  -- Exclude system tables.
and num_rows > 0  -- Ignore empty Tables.
order by num_rows desc -- Biggest first.
;

注意:这些是估算值,使用收集统计信息更加准确:

exec dbms_utility.analyze_schema(user,'COMPUTE');


这些统计信息可能是"null"(`num_rows`,`avg_row_len`),您需要先通过以下语句进行一些分析:`ANALYZE TABLE your_table COMPUTE STATISTICS`

3> Justin Cave..:

首先,我一般会提醒说,收集表统计数据以进行空间分析是一件有潜在危险的事情.收集统计信息可能会更改查询计划,尤其是在DBA已配置使用您的调用未使用的非默认参数的统计信息收集作业的情况下,并且将导致Oracle重新解析使用所讨论的表的查询,这可能是性能击中.如果DBA故意留下一些没有统计信息的表(如果您OPTIMIZER_MODE的选择是CHOOSE则常见),收集统计信息可能导致Oracle停止使用基于规则的优化器并开始使用基于成本的优化器进行一组查询,这可能是一个主要的性能如果在生产中意外地完成了头痛.如果您的统计信息准确无误,则可以查询USER_TABLES(或ALL_TABLESDBA_TABLES)直接不打电话GATHER_TABLE_STATS.如果您的统计数据不准确,可能有原因并且您不想打扰现状.

其次,与SQL Server sp_spaceused程序最接近的等价物可能是Oracle的DBMS_SPACE程序包.Tom Kyte有一个很好的show_space程序,它为这个包提供了一个简单的界面,并打印出类似于打印输出的信息sp_spaceused.



4> Tony Andrews..:

首先,在桌面上收集优化器统计信息(如果您还没有):

begin
   dbms_stats.gather_table_stats('MYSCHEMA','MYTABLE');
end;
/

警告:正如Justin在他的回答中所说,收集优化器统计数据会影响查询优化,不应该在没有适当注意和考虑的情况下完成!

然后从生成的统计信息中查找表占用的块数:

select blocks, empty_blocks, num_freelist_blocks
from   all_tables
where  owner = 'MYSCHEMA'
and    table_name = 'MYTABLE';

分配给该表的块总数是块+ empty_blocks + num_freelist_blocks.

blocks是实际包含数据的块数.

将块数乘以使用的块大小(通常为8KB)以获得消耗的空间 - 例如17个块x 8KB = 136KB.

要一次对架构中的所有表执行此操作:

begin
    dbms_stats.gather_schema_stats ('MYSCHEMA');
end;
/

select table_name, blocks, empty_blocks, num_freelist_blocks
from   user_tables;

注意:阅读此AskTom线程后对上述内容所做的更改



5> Sergey Stadn..:

我修改了WW的查询以提供更详细的信息:

SELECT * FROM (
  SELECT
    owner, object_name, object_type, table_name, ROUND(bytes)/1024/1024 AS meg,
    tablespace_name, extents, initial_extent,
    ROUND(Sum(bytes/1024/1024) OVER (PARTITION BY table_name)) AS total_table_meg
  FROM (
    -- Tables
    SELECT owner, segment_name AS object_name, 'TABLE' AS object_type,
          segment_name AS table_name, bytes,
          tablespace_name, extents, initial_extent
    FROM   dba_segments
    WHERE  segment_type IN ('TABLE', 'TABLE PARTITION', 'TABLE SUBPARTITION')
    UNION ALL
    -- Indexes
    SELECT i.owner, i.index_name AS object_name, 'INDEX' AS object_type,
          i.table_name, s.bytes,
          s.tablespace_name, s.extents, s.initial_extent
    FROM   dba_indexes i, dba_segments s
    WHERE  s.segment_name = i.index_name
    AND    s.owner = i.owner
    AND    s.segment_type IN ('INDEX', 'INDEX PARTITION', 'INDEX SUBPARTITION')
    -- LOB Segments
    UNION ALL
    SELECT l.owner, l.column_name AS object_name, 'LOB_COLUMN' AS object_type,
          l.table_name, s.bytes,
          s.tablespace_name, s.extents, s.initial_extent
    FROM   dba_lobs l, dba_segments s
    WHERE  s.segment_name = l.segment_name
    AND    s.owner = l.owner
    AND    s.segment_type = 'LOBSEGMENT'
    -- LOB Indexes
    UNION ALL
    SELECT l.owner, l.column_name AS object_name, 'LOB_INDEX' AS object_type,
          l.table_name, s.bytes,
          s.tablespace_name, s.extents, s.initial_extent
    FROM   dba_lobs l, dba_segments s
    WHERE  s.segment_name = l.index_name
    AND    s.owner = l.owner
    AND    s.segment_type = 'LOBINDEX'
  )
  WHERE owner = UPPER('&owner')
)
WHERE total_table_meg > 10
ORDER BY total_table_meg DESC, meg DESC
/



6> 小智..:

对于子分区表和索引,我们可以使用以下查询


    SELECT owner, table_name, ROUND(sum(bytes)/1024/1024/1024, 2) GB
    FROM
    (SELECT segment_name table_name, owner, bytes
     FROM dba_segments
     WHERE segment_type IN ('TABLE', 'TABLE PARTITION', 'TABLE SUBPARTITION')
     UNION ALL
     SELECT i.table_name, i.owner, s.bytes
     FROM dba_indexes i, dba_segments s
     WHERE s.segment_name = i.index_name
     AND   s.owner = i.owner
     AND   s.segment_type IN ('INDEX', 'INDEX PARTITION', 'INDEX SUBPARTITION')
     UNION ALL
     SELECT l.table_name, l.owner, s.bytes
     FROM dba_lobs l, dba_segments s
     WHERE s.segment_name = l.segment_name
     AND   s.owner = l.owner
     AND   s.segment_type = 'LOBSEGMENT'
     UNION ALL
     SELECT l.table_name, l.owner, s.bytes
     FROM dba_lobs l, dba_segments s
     WHERE s.segment_name = l.index_name
     AND   s.owner = l.owner
     AND   s.segment_type = 'LOBINDEX')
    WHERE owner in UPPER('&owner')
    GROUP BY table_name, owner
    HAVING SUM(bytes)/1024/1024 > 10  /* Ignore really small tables */
    ORDER BY SUM(bytes) DESC
    ;



7> ConcernedOfT..:

IIRC您需要的表是DBA_TABLES,DBA_EXTENTS或DBA_SEGMENTS和DBA_DATA_FILES.如果您在计算机上没有管理权限,则可以查看表的USER_和ALL_版本.

推荐阅读
家具销售_903
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有