1

我想将一个整数列添加到具有大量行和许多索引的表中(它是一个数据仓库事实表)。

为了使行宽尽可能窄,此表中的所有列都定义为非空。所以我希望新列不为空,默认为零。

根据经验,添加此列将需要一些时间,可能是因为数据库需要使用填充值的新列重写所有行。这大概会涉及更新聚集索引和所有非聚集索引。

所以我应该在添加列之前删除所有索引,然后重新创建它们。或者有没有更简单的方法来做到这一点?

另外我真的不明白为什么添加一个可以为空的列要快得多。为什么这不涉及重写记录并为每一行翻转一个额外的 Is Null 位。

4

3 回答 3

4

这将需要更新聚集索引,是的 -毕竟这是表数据

但我不明白为什么必须更新任何非聚集索引 - 您的新列不会成为任何非聚集索引的成员。

此外,我看不出在这种情况下删除和重新创建索引会对您有什么好处。如果您从另一个表或数据库批量加载数百万现有行 - 是的,那么它可能会更快(由于 INSERT 更快) - 但添加列并不会真正受到任何索引或约束的影响,我不认为。

马克

于 2009-04-16T15:23:26.630 回答
0

“而且我真的不明白为什么添加一个可以为空的列要快得多。为什么这不涉及重写记录并为每一行翻转一个额外的 Is Null 位。”

添加可为空的列只会更改表的定义。个人记录不受影响。

于 2009-04-16T18:38:08.893 回答
0

SQL Server 是一个面向行的数据库。这与面向列的数据库形成对比。这意味着在 SQL Server 中,给定行的所有数据都存储在磁盘上。让我们举个例子:

假设您有一个包含 3 列的 Customer 表,FirstName、MiddleInitial 和 LastName。然后,假设此表中有 Jabba T. Hutt、Dennis T. Menace 和 George W. Bush 的 3 条记录。

在面向行的数据库(如 SQL Server)中,记录将按如下方式存储在磁盘上:

贾巴,T,赫特;丹尼斯,T,威胁;乔治,W,布什;

相反,面向列的数据库会将记录存储在磁盘上,如下所示:

贾巴、丹尼斯、乔治;T、T、W;赫特威胁,布什;

列组合在一起而不是行。

现在,当您在面向行的数据库(例如 SQL Server)中向表中添加一列时,必须将每列的新数据插入到现有行旁边,从而转移需要大量读/写的行操作。因此,如果您要为默认为“先生”的客户前缀插入一个新列,您会得到:

贾巴先生,T,赫特先生;丹尼斯先生,T,威胁;乔治、W、布什先生;

如您所见,所有原始数据都已向右移动。另一方面,当您插入一个默认为 NULL 的新列时,不必将新数据放入现有行中。因此,移位更少,需要更少的磁盘读/写操作。

当然,这是对磁盘上实际情况的过度简化。在处理索引、页面等时,还有其他一些事情需要考虑。但是,它应该可以帮助您了解情况。

为了澄清起见,我根本不建议您迁移到面向列的数据库,我只是将这些信息放在那里以帮助解释面向行的含义。

于 2009-04-16T15:17:49.810 回答