压缩,碎片整理,回收空间,shrinkdatabase与shrinkfile

Gen*_*нин 2 sql t-sql sql-server storage memory-management

[1]指出:

  • "当从堆中删除数据时,页面上的数据不会被压缩(回收).如果堆页面的所有行都被删除,通常整个页面都无法回收"
  • "ALTER INDEX重建和重组选项不能用于对堆中的空间进行碎片整理和回收(但它们可用于对堆上的非聚簇索引进行碎片整理).
    如果要对SQL Server 2005中的堆进行碎片整理,则有三个选项:
    • 1)在堆上创建聚簇索引,然后删除聚簇索引;
    • 2)使用SELECT INTO将旧表复制到新表; 要么
    • 3)使用BCP或SSIS将数据从旧表移动到新表.
      在SQL Server 2008中,ALTER TABLE命令已更改,因此它现在可以重建堆"

Plz解释我:
MS SQL Server 2005中压缩,(反)碎片,回收空间,缩小文件和收缩数据库有什么区别?
shrinkfile和shrinkdatabase在MS SQL Server 2005中完成了什么?

更新:
问题的灵感来自于[2]中的讨论 - 如何在MS SQL Server 2005中缩小数据库?

Update2: @PerformanceDBA,
聪明!你在一周内获得了超过500+.这太了不起了!

您的图表
再次感谢您的时间.
我稍后会问,而不是在这里.
内部结构不是我的主要关注点,也不是最容易的.

它非常简洁,通常不会引起任何疑问或问题.

我更喜欢一些工具,描述/说明,技术,围绕它来发展我的疑虑,问题和讨论.
Plz见,例如,我的问题:

它们基本上与我提出的问题重复,但无法在stackoverflow.com中讨论

Update3: @PerformanceDBA,
再次感谢,我的问题的主要目的是确定如何解决具体问题的方法(基于并避免做什么),这些问题包含了你帮助过的文档,文章,讨论,答案等等检测.

目前我在这方面没有进一步的(无法解决和阻止我)问题.


[1]
Brad McGehee.Brad的索引指南(2009年6月11日)
http://www.simple-talk.com/sql/database-administration/brads-sure-guide-to-indexes/
[2]
回答和反馈问题"缩小数据库低于其初始大小"
/sf/ask/248071911/#3774639

Per*_*DBA 8

一个多月没有人碰过这个.

前三个答案实际上是我为你制作图表,你没有费心去消化和提出有关......的问题,它经常被用作讨论的平台.

(这是我更详细的Sybase图表的精简版本,我已经为MS上下文进行了诅咒.如果您需要完整的Sybase集,那么该文档底部会有一个链接.)

因此,我也不会花太多时间在你身上.并且请不要求链接到"参考站点",没有这样的东西(可用的是非技术垃圾),这正是我有自己的图表的原因; 很少有人了解MS SQL Internals.

回收空间

这是正确的用语.MS不会从页面中删除已删除的行,也不会从范围中删除已删除的页面.回收空间是一个通过堆的操作,并删除未使用的(a)行和(b)页.当然,这会更改RowIds,因此必须重建所有非聚集索引.

压缩

在粘贴文本的上下文中:与回收空间相同.

碎片整理

全面清除未使用空间的操作.有三个级别:

I.跨所有对象的数据库(AllocationUnits)

II.对象(范围和页面),页面链,拆分页面,溢出页面

III.仅限堆(没有聚集索引),帖子的主题

SHRINKFILE

相当不同的操作,减少设备(文件)上分配的空间.这将删除未使用的AllocationUnits(因此"收缩"),但它与去碎片AllocationUnits不同.

SHRINKDATABASE

为数据库做同样的事情; 数据库在所有设备上使用的所有设备分配.

对评论的回应

SSC的海报是无能为力的,并没有直接解决你的问题.

  • 没有集群表这样的东西(CREATE CLUSTERED TABLE失败)
  • 有一个集群索引(CREATE CLUSTERED INDEX成功)
  • 根据我的图表,它是一个单一的物理结构; 聚集索引包含行,因此消除了堆
  • 如果没有Clustered索引,则有两种物理结构:Heap和单独的Nonclustered Index

现在,在你使用DBCC进入潜水之前,这个级别太低,无知的人无法识别,更不用说解释为什么以及为什么,你需要了解并确认上述内容:

  • 创建一个Table_CI(我们打算添加一个CI,仍然没有集群表这样的东西)
  • 为其添加一个唯一的聚簇索引UC_PK
  • 添加几行

  • 创建一个表堆

  • 为其添加一个唯一的非聚集索引NC_PK
  • 添加几行

  • SELECT*FROM sysindexes WHERE id = OBJECT_ID("Table_CI")

  • SELECT*FROM sysindexes WHERE id = OBJECT_ID("Heap")

  • 请注意,每个sysindexes条目都是一个完整,独立的数据存储结构(请查看列)

  • 考虑输出
  • 与我的图表比较
  • 与宇宙中的垃圾相比

将来,我不会回答有关宇宙中混乱垃圾的问题,以及其他网站上不正确和错误信息的帖子(我不在乎他们是MS认证专家,他们已经证明他们无法检查他们的数据库并确定正确的信息)

有一个原因我打算创建准确的图表(手册,图片和所有可用信息来自MS,都是垃圾;没有用你从:权威机构寻找准确的信息",因为"权威"在技术上破产).

即使盖尔终于到处走了, 我怀疑在摆弄低水平内部结构之前,你会从更多阅读指数整体架构中受益.

除外,没有.这不是混乱,非技术性和不一致性.

我有理由创建准确的图表.

回到DBCC.盖尔是完全错误的.在聚簇索引(包括行)中,单个页面包含行.是的,行.这是索引的叶级.它有一个B树,它位于页面的顶部,但它很小,你看不到它.查看sysindexes输出.root和firstpage指针指向页面; 这是聚集索引的根源.当你潜入海洋时,你需要知道要寻找什么,在哪里找到它,否则你将无法找到你想要的东西,你会被你偶然发现的漂浮物和jetsam分散注意力.

现在看看NCI和堆的两个单独结构.

哦,MS已经从使用OAM术语变为数据结构为索引的IAM.这引起了混乱.就数据结构(sysindexes中的条目)而言,它们都是对象; 他们可能是也可能不是指数.重点是,谁在乎,我们知道它是什么,它是一个ObjectAllocationMap ......如果你正在看NCI,那么它就是一个IndexObjectAllocationMap; 如果您正在查看堆,它是一个HeapObjectAllocMap.我会让你思考一下CI的情况.在追逐或使用它时(找到属于OBJECT的页面,没关系,它们都是对象.当你这样做时,你需要知道,有些对象有一个PageChain,有些对象没有;另一个你的问题.CIs有它们; NCIs和Heaps没有.

Gail Shaw:"我怀疑这些内部结构在任何地方都有记录.毕竟,我们正在使用未记录的功能.索引的定义取决于您询问的人和您的目标.

ROTFLMAO.我的身边受伤了,我看不懂随后的帖子.这些人应该是聪明的人吗?在IT世界工作?定义改变?什么温度或一天的时间?那是SQL Server Central吗?不是边远地区?

当MS从Sybase窃取SQL Server时,文档非常扎实.对于每个主要版本,他们"重写"它,文档变得更弱和更蓬松(回想我们在另一篇文章中的讨论).现在我们有可爱的图片,让人们感觉很好,但技术上是不准确的.这就是为什么像你这样认真的人有问题.图片甚至不符合手册中的文字.

无论如何,定义不会改变.这就是定义的定义.它们在任何情况下都是正确的.而嗯,你正在使用的功能是一个普通的,有记录的功能.自1987年以来.除了MS在某个地方丢失了,没有人能找到它.您将不得不询问过去常见的Sybase Guru,他们会记住他们获得的代码中的确切数据结构.如果你真的很幸运,他将了解MoronSociety在2000年,2005年,2008年引入的差异.他甚至可能只有一个准确的图表,与您的盒子上的sysindexes和DBCC的输出相匹配.如果你找到他,亲吻他的戒指并用金子洗澡.锁定你的女儿.

(不严重,我的双方正在杀我,欢乐正在溢出).

现在你明白为什么我不回答有关宇宙中混乱垃圾的问题吗?MoronSociety里有很多蠢货.

-----

盖尔再次:

"扫描:
索引扫描是对索引中所有叶子页面的完整读取.当对聚簇索引进行索引扫描时,它是除了名称之外的所有表扫描.
当查询处理器完成索引扫描时,它始终是索引中所有叶子页面的完整读取,无论是否返回所有行.它从不是部分扫描.
扫描不仅涉及读取索引的叶级别,更高级别页面也作为索引扫描的一部分被读取."

必须有一个她以快风命名的理由.她写"书"?是的,幻想小说.热气球适合气球专家而非IT专业人士.

完整和完整的驱动.索引扫描的全部内容以及为什么它更适合于表扫描,因为它试图避免表扫描,是: - 引擎(执行查询树)可以直接转到索引(聚簇或非聚簇,在这一点上) - 导航B树以找到开始的地方(到目前为止,与获得几行时相同,即不扫描) - B树(来自任何好处)技术图)是几页,每页包含许多索引条目,所以它非常快 - 这是根加非叶级别 - 直到找到符合条件的叶级条目 - 从那一点开始,它确实SCAN,顺序,通过所述索引的LEAF级别(胖蓝箭头)

  • 现在对于NCI来说,如果你还记得你的作业,那就意味着叶级页面已经满了index_leaf_level_entry + CI_key
  • 所以它横跨NCI叶水平扫描顺序(这就是为什么只有在NCIS的叶级一个PageChain,以便它可以在导航)
  • 但跳到HEAP上的所有地方,以获取数据行

  • 但对于CI,叶级是数据行(数据页,只有数据行,这就是为什么你不能看到他们的"指数";非叶级CI页面仅包含index_entries纯索引页)

  • 因此,当它扫描索引leaf_level顺序,使用PageChain的,它是扫描数据顺序地,它们是相同的操作(脂肪绿色箭头)
  • 没有堆
  • 没有跳跃

为了比较,那么,一个TABLE SCAN(仅限MS): - 堆上没有PageChain - 没有选择,但是从头开始 - 并读取每个数据页 - 其中许多将被分段(包含剩余的未使用空间)删除或转发的行) - 其他人将完全为空

整个意图是,优化器已经决定不进行表(堆)扫描,它可以进行索引扫描(因为它需要的不是全部数据,它可以找到起点那些数据通过一些索引).如果你看看你的SHOWPLAN,即使是检索一个独特的PK行,它也会显示"INDEX SCAN".所有这些意味着,它将首先导航B树,以找到至少一行.然后它可以扫描叶子级别,直到找到一个终点.如果它是一个覆盖的查询,它永远不会转到数据行.

群集指数无可替代.