DB2统计表和索引占用空间量


数据库版本是V9.7,要统计数据库中表及其上的索引占用的空间大小。


初看这个问题,感觉很简单,马上写出了如下的查询语句:


select sum(data_object_l_size + index_object_l_size + dictionary_size/1024.0)/1024.0
from table(sysproc.admin_get_tab_info_v97('${schema}','${name}'));
注:库中没有 long, lob, xml 数据类型,所以忽略了相关字段。另外统计的是逻辑大小,也可以统计物理大小。


然而这样查出所有表的占有空间后,发现与表空间的已使用量小很多,查阅文档后发现 sysproc.admin_get_tab_info_v97 中汇报的索引大小不包含分区表上的非分区索引,于是按文档中的指示,通过 sysproc.admin_get_index_info 来查索引的大小。我想当然的写出了如下语句:


select a.size_in_mb + coalesce(b.size_in_mb,0)
from (select sum(data_object_l_size + dictionary_size/1024.0)/1024.0 size_in_mb
      from table(sysproc.admin_get_tab_info_v97('${schema}','${name}'))) a
left join (select sum(index_object_l_size)/1024.0 size_in_mb
           from table(sysproc.admin_get_index_info('T','${schema}','${name}'))) b
on 1=1;
问题还没结束,新查法得到的所有表和索引总大小又比表空间的已使用量高很多。于是再仔细看文档,这个 sysproc.admin_get_index_info 返回的结果比较特别,根据表和索引的范围分区有以下三种情况:
1.如果是非分区表上的索引,那么汇报的是表上所有索引的总大小,而不是那个索引的单独大小;
2.如果是分区表的分区索引,那么汇报的是那个数据分区上的所有索引的总大小,即多个索引的部分大小之和;
3.如果是分区表上的非分区索引,汇报的才是这个索引在每个数据库节点的单独大小。


弄清了上面的三点,再把查询语句改成下面这样的,就得到了与表空间已使用量一致的统计结果了。


select a.size_in_mb + coalesce(b.size_in_mb,0)
from (select sum(data_object_l_size + dictionary_size/1024.0)/1024.0 size_in_mb
      from table(sysproc.admin_get_tab_info_v97('${schema}','${name}'))) a
left join (select sum(index_object_l_size)/1024.0 size_in_mb
           from (select * from (select index_object_l_size,row_number() over(partition by dbpartitionnum) sn
                                from table(sysproc.admin_get_index_info('T','${schema}','${name}'))
                                where index_partitioning='') where sn=1
                 union all
                 select * from (select index_object_l_size,row_number() over(partition by dbpartitionnum,datapartitionid) sn
                                from table(sysproc.admin_get_index_info('T','${schema}','${name}'))
                                where index_partitioning='P') where sn=1
                 union all
                 select index_object_l_size,1 sn
                 from table(sysproc.admin_get_index_info('T','${schema}','${name}')) where index_partitioning='N')
          ) b on 1=1;
也可以写成下面这样的:


select a.size_in_mb + coalesce(b.size_in_mb,0)
from (select sum(data_object_l_size + dictionary_size/1024.0)/1024.0 size_in_mb
      from table(sysproc.admin_get_tab_info_v97('${schema}','${name}'))) a
left join (select sum(index_object_l_size)/1024.0 size_in_mb
           from (select t1.index_object_l_size,row_number() over(partition by t1.dbpartitionnum,t2.index_objectid) sn
                 from table(sysproc.admin_get_index_info('T','${schema}','${name}')) t1,
                      (select iid,index_objectid,0 datapartitionid from syscat.indexes
                       where tabschema='${schema}' and tabname='${name}' and iid not in (select iid from syscat.indexpartitions where tabschema='${schema}' and tabname='${name}')
                       union all
                       select iid,indpartitionobjectid index_objectid,datapartitionid from syscat.indexpartitions
                       where tabschema='${schema}' and tabname='${name}') t2
                 where t1.iid=t2.iid and t1.datapartitionid=t2.datapartitionid
          ) where sn=1
) b on 1=1;
起初看似简单的问题,却让我两次犯错。更甚的是,文档上对这几个字段的特性有明确说明,我居然视而未见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值