[翻译]为什么你不要收缩数据库文件
我最大的一个热点问题是关于收缩数据文件,虽然在微软的时候,我自己写了相关收缩数据文件代码,我再也没有机会去重写它,让它操作起来更方便。我真的不喜欢收缩。
现在,不要混淆了收缩事务日志文件和收缩数据文件,当事务日志文件的增长失控或为了移除过多的VLF碎片(这里和这里看到金佰利的优秀文章),然而,收缩事务日志数据文件不要频繁使用(罕见的操作)并且不应是你执行定期维护计划的一部分。
收缩数据文件应该执行得甚至更少。这就是为什么——数据文件收缩导致产生了大量索引碎片,让我用一个简单并且你可以运行的脚步来演示。下面的脚本将会创建 一个数据文件,创建一个10MB大小的“filler”表,一个10MB大小的“production”聚簇索引,然后分析新建的聚集索引的碎片情况。
-- Create the production table, which will be after the filler table in the data file CREATE TABLE [ProdTable]( [c1] INT IDENTITY, [c2] CHAR (8000) DEFAULT production);
聚集索引的逻辑碎片在收缩数据文件前大约接近0.4%。[但是我测试结果是0.54%,如上图所示,不过也算是接近0.4%]
现在我删除filter表,运行收缩数据文件命令后,重新分析聚集索引的碎片化。
下面是我的执行结果,作者执行结果,请看原文:
原文:
Wow! After the shrink, the logical fragmentation is almost 100%. The shrink operation *completely* fragmented the index, removing any chance of efficient range scans on it by ensuring the all range-scan readahead I/Os will be single-page I/Os.
译文:
哇,真是恐怖!数据文件收缩后,索引的逻辑碎片几乎接近100%,收缩数据文件导致了索引的完全碎片化。消除了任何关于它的有效范围扫描的机会,确保所有执行提前读范围扫描的 I/O 在单页的 I/O操作
为什么会这样呢? 当单个数据文件收缩操作一次后,它会用GAM位图索引找出数据文件中分配最高的页,然后尽可能的向前移动到文件能够移动的地方,就这样子,在上面的例子中,它完全反转了聚集索引,让它从非碎片化到完全碎片化。
同样的代码用于DBCC SHRINKFILE, DBCC SHRINKDATABASE,以及自动收缩,他们同样糟糕,就像索引的碎片化,数据文件的收缩同样产生了大量的I/O操作,耗费大量的CPU资源,并且 生成了*load*事务日志,因为任何操作都会全部记录下来。
数据文件收缩决不能作为定期维护的一部分, 你决不能启用“自动收缩”属性,我尝试把它从SQL 2005和SQL 2008产品中移除,它还存在的唯一原因是为了更好的向前兼容,不要掉入这样的陷阱:创建一个维护计划,重新生成所有索引,然后尝试回收重建索引耗费的空 间采取收缩数据文件 — — 这就是你做的生成了大量事务日志,但实质没有提高性能的零和游戏。
所以,你为什么要运行一个收缩呢,?举例来说,如果你把一个相当大的数据库删除了相当大的比例,该数据库不太可能增长,或者你需要转移一个数据库文件前先清空数据文件?
译文:
我很想推荐的方法如下:
创建一个新的文件组 将所有受影响的表和索引移动到一个新的文件组用CREATE INDEX ... WITH (DROP_EXISTING=ON)的脚本,在移动表的同时,删除表中的碎片。 删掉那些你准备收缩的旧文件组,你反正要收缩(或缩小它的方式下来,如果它的主文件组)。基本上你需要提供一些更多的空间,才可以收缩的旧文件,但它是一个更清晰的设置。
原文:
The method I like to recommend is as follows:
Create a new filegroup Move all affected tables and indexes into the new filegroup using the CREATE INDEX … WITH (DROP_EXISTING = ON) ON syntax, to move the tables and remove fragmentation from them at the same time Drop the old filegroup that you were going to shrink anyway (or shrink it way down if its the primary filegroup)Basically you need to provision some more space before you can shrink the old files, but it’s a much cleaner mechanism.
如果你完全没有选择需要收缩日志文件,请注意这个操作会导致索引的碎片化,你应该在收缩数据文件采取一些步骤消除它可能导致的性能问题,唯一的方式是用 DBCC INDEXDEFPAGE或 ALTER INDEX ...REORGANIZE消除索引的碎片不要引起数据文件的增长,这些命令要求扩展空间8KB的页代替重建一个新的索引在索引重建操作中。
底线 — — 尽量避免不惜一切代价运行数据文件收缩
------------------------------------------------分割线----------------------------------------
所以,还在用作业定期收缩数据文件或数据库开启了“自动收缩”属性的朋友们,请及时纠正你们的错误认识吧!
潇湘隐者 网名潇湘隐者/潇湘剑客、英文名Kerry,兴趣广泛,广泛涉猎,个性随意,不善言辞。执意做一名会写代码的DBA,混迹于IT行业
相关文章
- php 创建文件
- 最全三大框架整合(使用映射)——数据库资源文件jdbc.properties
- Unity获取指定资源目录下的所有文件
- Windows 2003 Server C盘空间被IIS日志文件消耗殆尽案例
- 05-创建对象-关系映射文件和数据库
- 数据库内核月报 - 2015 / 08-PgSQL · 答疑解惑 · 归档进程cp命令的core文件追查
- C/C++基础讲解(六十二)之系统篇(显示目录内容/读取磁盘文件)
- C#读写txt文件的两种方法介绍
- SQL Server 2008 R2 安装时提示“Reporting Services目录数据库文件存在”
- matlab与C++以.mat文件方式进行数据相互流动
- .NET平台开源项目速览(3)小巧轻量级NoSQL文件数据库LiteDB
- atitit.跨语言实现备份mysql数据库 为sql文件特性 api 兼容性java c#.net php js
- Android 拷贝SQLite数据库文件到手机的内部存储
- IBM HTTP Server Plugin默认plugin-key.kdb 密钥数据库文件默认个人证书密码过期分析与解决方法
- 成功解决LINK : fatal error LNK1181: 无法打开输入文件“avdevice.lib” error: command 'D:Program Files (x86)Micr
- 【Android 逆向】使用 DB Browser 查看并修改 SQLite 数据库 ( 从 Android 应用数据目录中拷贝数据库文件 | 使用 DB Browser 工具查看数据块文件 )
- 利用kettle组件导入excel文件到数据库
- leaflet加载KML文件,显示图形(方法2)
- Mariadb 数据库修改打开文件限制open_files_limit——筑梦之路
- 【诊断数据库文件-CDD】创建速成班-北汇信息小课堂(一)
- 关于时间序列数据库的思考——(1)运用hash文件(例如:RRD,Whisper) (2)运用LSM树来备份(例如:LevelDB,RocksDB,Cassandra) (3)运用B-树排序和k/v存储(例如:BoltDB,LMDB)
- 3. OD-爆破有钥匙的exe(有验证文件,如KeyFile.dat)
- [ MySQL ] 使用Navicat进行MySQL数据库备份 / 还原(Part 2:备份.sql文件方式)