【问题标题】:ORACLE - Get database size per partitionORACLE - 获取每个分区的数据库大小
【发布时间】:2021-07-07 22:02:17
【问题描述】:

我正在寻找一个 SQL 查询来给我这种输出:

table_owner  table_name  partition_name  data (bytes)  indexes (bytes)
MY_OWNER     MY_TABLE    P01             12345678      23456789
MY_OWNER     MY_TABLE    P02             34567890      45678901
MY_OWNER     MY_TABLE    P03             56789012      67890123
...

我访问了How do I calculate tables size in Oracle,但没有找到我要查找的内容,因为它始终针对每个表、每个所有者/架构,但从不针对每个分区。

我知道字节数可能不能真正代表现实,因为它可能是“磁盘中的实际字节数”和/或“预分配的字节数”(实际数据只能使用该预分配空间的 1%),但我愿意拥有这个值,即使它是预分配的或实际使用的字节数。

注意事项:

  • 使用Oracle 18c Enterprise
  • 我们关心系统表、ORACLE 表、维护表等,只关注我自己为数据创建的表
  • 表空间名称始终对于同一架构中的所有表中的所有分区都相同,当然每个架构的每个表空间名称都不同
  • 无需在KbMbGb 甚至Tb 中四舍五入,如果可能的话,我更喜欢bytes
  • 不需要pourcentage,不需要最大可用空间
  • 我只使用partitions不使用任何subpartitions
  • 如果我们需要在每个模式、表和分区上循环,我可以使用 PL/SQL 块
  • 我猜我可以由任何用户运行此查询

有什么想法吗?

【问题讨论】:

  • 未分区的表呢?具有分区索引的表是不同的表空间 [s] 呢?将 dba_segments 与 dba_indexes 结合起来会让您接近。
  • @ik_zelf:确实,所以首先我们不关心未分区的表,因为所有 MY 表都肯定是分区的(至少,如果是新模式,它们至少有一个分区,不管是什么原因)第二表空间名称在整个架构中始终相同,并且每个架构/所有者都有唯一的表空间名称
  • @ik_zelf 感谢您注意到我没有澄清的这些要点

标签: oracle


【解决方案1】:

你好,像这样的吗?我们使用我修改过的类似查询。您必须根据需要更改 ORDER BY 子句,并且可能将其限制为一个所有者,因为它可能需要很长时间才能占用整个数据库。出于这个原因,我们不连接段的大小,而只查看行和块。

select "OWNER", "OBJECT", "TYPE", "PARTITION_NAME", "NUM_ROWS", "GB", "PARTITION_POSITION", "DUMMY"
from ((select tp.table_owner owner, tp.TABLE_NAME object, 'TABLE' type, tp.PARTITION_NAME,ROUND(s.bytes/1024/1024/1024, 2) GB, tp.NUM_ROWS,tp.PARTITION_POSITION, 1 dummy
  from dba_tab_partitions tp, dba_tables t, dba_segments s
  where t.table_name=tp.table_name and t.table_name=s.segment_name )
union 
 (select ip.index_owner owner,ip.INDEX_NAME object, 'INDEX' type, ip.PARTITION_NAME,ROUND(s.bytes/1024/1024/1024, 2) GB,ip.NUM_ROWS, ip.PARTITION_POSITION, 2 dummy
  from dba_ind_partitions ip, dba_indexes i, dba_tables t, dba_segments s
   where i.index_name=ip.index_name and i.table_name=t.table_name and i.index_name=s.segment_name )
union 
(select lp.table_owner owner,lp.LOB_NAME object, 'LOB' type, lp.PARTITION_NAME, 0, ROUND(s.bytes/1024/1024/1024, 2) GB,lp.PARTITION_POSITION, 3 dummy 
from dba_lob_partitions lp, dba_tables t, dba_segments s
  where t.table_name=lp.table_name and t.table_name=s.segment_name ))
order by 8,1,2,7;

【讨论】:

  • 谢谢@sandman。它看起来很棒而且很有效。但是,对于 INDEX 部分,我无法链接分区名称。我有这个TABLELOB: MY_OWNER MY_TABLE INDEX P1 ... 但是,对于INDEX,我有类似:MY_OWNER MY_TABLE INDEX SYS_IL_Pxxxxxx ... 为什么?为什么我不能为 INDEX 提供相同的服务?是否有不能将SYS_IL_PxxxxxPxxx 等真实表名匹配的限制?
  • 好的,根据docs.oracle.com/en/database/oracle/oracle-database/12.2/sqlrf/…SYS_IL_Pxxxxxx 表示我没有为索引设置分区名称,这似乎是正确的,因为我从未设置任何名称。解决方案是正确的,但可能是适配器,请参阅上面/下面的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-17
  • 1970-01-01
相关资源
最近更新 更多