AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 147263
Accepted
user99201
user99201
Asked: 2016-08-19 14:32:50 +0800 CST2016-08-19 14:32:50 +0800 CST 2016-08-19 14:32:50 +0800 CST

堆上的压缩

  • 772

以下是Microsoft Docs中的一段:

作为 DML 操作的一部分,在堆中分配的新页面在重建堆之前不会使用 PAGE 压缩。通过删除和重新应用压缩或者通过创建和删除聚集索引来重建堆。

我不明白为什么会这样。如果我有一个具有指定压缩设置的堆,为什么不将它应用于属于该表的页面?

谢谢

sql-server compression
  • 2 2 个回答
  • 2092 Views

2 个回答

  • Voted
  1. Best Answer
    Solomon Rutzky
    2016-08-19T20:34:01+08:002016-08-19T20:34:01+08:00

    虽然我不知道导致差异的具体内部机制,但我可以说堆的管理(内部)与聚集索引(可能还有非聚集索引)略有不同:

    • 从堆中删除行以使一个或多个数据页为空(未分配行)并不一定会释放该空间。您可能需要在表上创建然后删除聚集索引,或者调用ALTER TABLE [TableName] REBUILD;(从 SQL Server 2014 开始?)。有关更多详细信息和选项,请参阅 Microsoft Docs 页面以了解DELETE。

    • 将单独的行(即不是基于集合的INSERT)插入堆中不会像使用聚集索引那样完全填充数据页。只要行有空间(数据和行开销)加上插槽数组的 2 字节开销,聚集索引将适合行。然而,堆中的数据页不使用页面上剩余的字节数,而是使用一个非常笼统的指标来指示页面的填充程度,并且报告的级别并不多。级别大致为:0%、20%、50%、80% 和 100% 满。并且它会切换到 100%,而仍有空间可容纳另一行(事实上,如果在基于集合的操作中插入相同数量的行,那么它会尽可能地填满页面)。当然,就像DELETE操作,重建堆将打包尽可能多的行,以适应数据页。

    现在考虑以下信息,取自页面压缩实施的 Microsoft Docs 页面的“页面压缩发生时”部分:

    ...随着数据被添加到第一个数据页,数据被行压缩。...当页面已满时,要添加的下一行启动页面压缩操作。审查整个页面;...

    因此,在写入数据页之前,它们需要 ALTER TABLE REBUILD、CREATE / DROP 或更改数据压缩设置(所有这些都重建堆)似乎与其他堆行为完全一致最佳。如果堆没有完全意识到“整个页面”(直到堆被重建)并且不知道页面何时肯定是满的,那么他们将不知道何时启动页面压缩操作(在处理更新和单-行插入)。

    另一个将进一步限制某些堆自动应用页面压缩(即使它们可以)的技术性是,应用压缩将需要重建该堆的所有非聚集索引(如果存在)。正如“数据压缩”的链接页面还指出:

    更改堆的压缩设置需要重建表上的所有非聚集索引,以便它们具有指向堆中新行位置的指针。

    所指的“指针”是行 ID (RID),它们是以下内容的组合:FileID、PageID 和页面上的插槽/位置。这些 RID 被复制到非聚集索引中。作为一个精确的物理位置,它们有时比使用聚集索引键遍历 b 树更快。但是,物理位置的一个缺点是它可以改变,这就是这里的问题。然而,聚集索引不会遇到这个问题,因为它们的键值被复制到非聚集索引中,作为返回聚集索引的指针。并且键值保持不变,即使它们的物理位置发生变化。

    另见:

    • 堆(没有聚集索引的表)的 Microsoft Docs 页面的“管理堆”部分:

      要重建堆以回收浪费的空间,请在堆上创建聚集索引,然后删除该聚集索引。

    • Microsoft Docs数据压缩页面的“使用行和页面压缩时的注意事项”部分:

      当堆配置为页面级压缩时,页面仅通过以下方式接收页面级压缩:

      • 数据是在启用批量优化的情况下批量导入的。
      • 使用 INSERT INTO ... WITH (TABLOCK) 语法插入数据,并且该表没有非聚集索引。
      • 通过使用 PAGE 压缩选项执行 ALTER TABLE ... REBUILD 语句来重建表。

      以及问题中引用的声明。

    • 14
  2. RLF
    2016-08-19T19:07:10+08:002016-08-19T19:07:10+08:00

    并非 SQL Server 中的每个机制都像我们认为的那样。

    Paul Randal 就管理该问题提出了强有力的建议。

    http://www.sqlskills.com/blogs/paul/a-sql-server-dba-myth-a-day-2930-fixing-heap-fragmentation/

    • 2

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve