【问题标题】:What really happens when I drop a column from a table?当我从表中删除一列时会发生什么?
【发布时间】:2014-05-19 15:53:47
【问题描述】:

我有一个 MS SQL Server 数据库。我只是在做一些实验,以确定某些操作需要多长时间,这样我们就可以在更新数据库时最大限度地减少网站的停机时间。我需要更改一个列的定义,但是表很大,所以这需要两个小时。所以方案B:我新建了一个列,将旧列的数据复制到新列,删除旧列,将新列重命名为旧列名。 (我在想我们可以在网站仍在运行的情况下复制数据,然后将其关闭足够长的时间以进行删除和重命名。也许这是一个愚蠢的想法,因为我如何确保在复制时不更新记录正在发生,但这与这个问题无关。)

现在让我感到困惑的部分是:

alter table add column: 0 秒。好的,我认为它只是向元数据添加了一个条目,并且引擎足够智能,可以处理尚未填充值的列。

update set newcolumn=oldcolumn 2 小时。这正是我所期望的。

Delete oldcolumn:0 秒。

现在这让我很困惑。如果复制数据需要2个小时,好吧删除不涉及进行类型格式转换,我可以看到它会更快,但我无法想象它可以在不到1秒的时间内处理数百万条记录。所以它必须只是更新元数据。但是,数据必须仍然存在于数百万条记录上,占用磁盘空间并且在我们读取记录时必须读取等等。删除的列会永远挂起吗?随着记录的更新,他们是否一次清理一条记录?他们会被一些后台工作清理干净吗?也许我应该做更多的实验:删除、更新所有记录通常需要更长的时间,但由于某种原因,这是一个特殊情况?

在我的实验中,该列是nvarchar(max),每条记录通常有 1000 个字符左右。由于其他列总共大约 150 个字节,因此该列是表的主体,所以这不是一个没有实际意义的问题。

【问题讨论】:

  • 据我了解,large value types 默认被存储out-of-row。例如,如果从 INT 迁移到 BIGINT,我怀疑你会得到不同的时间和行为。 technet.microsoft.com/en-us/library/…
  • @MatBailie 根据 TSQL 文档——当整个问题出现时我查阅了该文档——TEXT 字段存储在行外,但 VARCHAR(MAX) 字段存储在行内当大小低于某个阈值(我认为它是 8k)并且当高于该阈值时超出行。在我的例子中,表中的所有行的这个字段都低于阈值。这就是为什么我要更改数据类型的原因:它显着提高了性能。

标签: sql database sql-server-2012


【解决方案1】:

更新需要时间,因为它必须复制数据。

删除列只是调整一些元数据,但不影响实际数据。它所在的空间只是标记为空闲,并且可以在需要存储空间的任何时候被覆盖。 在此之前,甚至可以恢复 drop 列。

【讨论】:

    猜你喜欢
    • 2019-02-11
    • 1970-01-01
    • 1970-01-01
    • 2015-05-10
    • 1970-01-01
    • 2013-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多