• 包含LOB_Data列的表删除大量数据后表及数据库文件的收缩


    最近有一张表(内含varchar(max)字段),占用空间达到240G,删除历史数据后几十万条后,空间并未得到释放。

    然后用DBCC CLEANTABLE(0,tb_name,100)来释放删除记录后变长字段留下的空间,注意第三个参数为每个事务处理的行数,

    强烈建议使用,默认是0,将整个操作作为一个事务处理!全程锁表!!

    执行完DBCC CLEANTABLE后,发现表空间已经释放,占用空间几百兆,但此时还没完,我们数据库文件依然很大。

    于是我们尝试用DBCC SHRINKFILE来收缩库文件,结果却出人意料,文件并没有收缩到我们预想的大小,而是远远大于所有表

    的大小之和,100G之多,为什么?

    我们通过DBCC SHOWFILESTATUS命令查看分区状态,发现有大量的未使用分区,于是开始怀疑是区内页填充密度过低导致的,

    每个区8个页,如果有一个页不为空,SHRINKFILE命令也不会收缩该分区,因为SHRINKFILE命令是以区为单位的,它只会收缩掉

    完全空的分区。

    image

    所以下面我们来看一下“肇事”表的填充密度到底如何,这里我们使用DBCC SHOWCONFIG(‘TB’)命令:

    image

    可以看到,虽然这张表的区的利用率比较低,为25.76%[34:132],即本来用34个分区就可以容纳的数据,它用了132个分区来容纳,

    但是远远不可能造成上面199万个区的空间耗费!这到底是怎么回事!!

    没错,bug再一次显了神威!相关KB:http://support.microsoft.com/kb/2967240/en-us

    那么还有没有其它方法呢?答案是肯定的,那就是重建该对象:

    方法1:重新一张结构一样的表,将原表数据导入新表,干掉原表,重命名新表;

    方法2:将现有数据导出,TRUNCATE表,然后再将数据导回;

    另外,经过测试,上面KB中提出的CU13 FOR SQL SERVER 2008 R2 SP2,安装之后并不能使DBCC SHRINKFILE生效,故应该为避免以上情景的出现!

  • 相关阅读:
    Linux安装配置tomcat
    linux 安装jdk
    让/etc/profile文件修改后立即生效
    group by 和聚合函数
    mysql插入日期 vs oracle插入日期
    Thinkphp学习笔记-删除缓存
    Thinkphp错误-phpMyAdmin 尝试连接到 MySQL 服务器,但服务器拒绝连
    Thinkphp学习笔记-模板赋值
    Thinkphp学习笔记-模板主题
    Windows-设置系统服务不开机启动
  • 原文地址:https://www.cnblogs.com/zc_0101/p/3979794.html
Copyright © 2020-2023  润新知