在SQL 2005中更改聚集索引(PK)的最佳方法
我有一个表,它在两列上有一个聚集索引——表的主键。 其定义如下:在SQL 2005中更改聚集索引(PK)的最佳方法,sql,sql-server-2005,indexing,primary-key,clustered-index,Sql,Sql Server 2005,Indexing,Primary Key,Clustered Index,我有一个表,它在两列上有一个聚集索引——表的主键。 其定义如下: ALTER TABLE Table ADD CONSTRAINT [PK_Table] PRIMARY KEY CLUSTERED ( [ColA] ASC, [ColB] ASC )WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY] 我想删除这个聚集索引PK并添加如下聚集索引,并使用非聚集索引添加主键约束,如下所示
ALTER TABLE Table ADD CONSTRAINT [PK_Table] PRIMARY KEY CLUSTERED
(
[ColA] ASC,
[ColB] ASC
)WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]
我想删除这个聚集索引PK并添加如下聚集索引,并使用非聚集索引添加主键约束,如下所示
CREATE CLUSTERED INDEX [IX_Clustered] ON [Table]
(
[ColC] ASC,
[ColA] ASC,
[ColD] ASC,
[ColE] ASC,
[ColF] ASC,
[ColG] ASC
)WITH (PAD_INDEX = ON, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, FILLFACTOR = 90, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = OFF) ON [PRIMARY]
ALTER TABLE Table ADD CONSTRAINT
PK_Table PRIMARY KEY NONCLUSTERED
(
ColA,
ColB
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
我打算删除PK聚集索引,然后添加新的聚集索引,然后添加非聚集主键索引,但我了解到删除现有聚集索引会导致表数据重新排序(请参见此处的答案),我认为这是不必要的。该表的内存不足1 TB,因此我确实希望避免任何不必要的重新排序
我的问题是,从现有结构到理想结构的最佳方式是什么
编辑:我只是想澄清一下。表是1TB,很遗憾,我没有空间创建临时表。如果有一种不创建临时表的方法,请让我知道
CREATE TABLE newtable (colA INT, colB INT)
- 将旧表中的所有值插入新表:
插入 变成牛顿表 挑选* 从桌子上CREATE TABLE newtable (colA INT, colB INT)
- 删除旧表: 升降台
- 将新表重命名为旧表 EXEC sp_重命名“新表”、“表”
- 建立索引: 更改表格 添加约束 PK_表主键非聚集 ( 可乐 马驹 )[主]上的(统计信息\u NORECOMPUTE=OFF,忽略\u DUP\u KEY=OFF,允许\u行\u锁=ON,允许\u页\u锁=ON)
这并不是对您的问题的完整回答,但请确保如果表中有任何其他索引,您首先删除这些索引。否则,SQL Server必须在删除聚集索引时重新生成所有聚集索引,然后在添加回新聚集索引时再次重新生成所有聚集索引。通常的步骤是:
如果您的表的大小达到1 TB,并且可能有很多行,我强烈建议不要让聚集索引变得那么胖 首先,删除和重新创建聚集索引将至少在所有数据周围移动一次,这一过程需要花费很长时间 其次,您尝试创建的大型复合聚集索引将显著增加所有非聚集索引的大小(因为它们包含每个叶节点上的整个聚集索引值,用于书签查找) 问题更多:你为什么要这么做??难道你不能用这些列添加另一个非聚集索引,以潜在地覆盖你的查询吗?为什么这必须是聚集索引??我看不出这有什么好处 有关索引,特别是聚集索引辩论的更多信息,请参阅关于SQL Server索引-非常有用
Marc聚集索引实际上不会改变存储在表中的数据的物理顺序。自SQL6.5以来就没有过这种情况
页面上的数据以正确的顺序存储。页面可以以任何物理顺序存储在磁盘上。这不是一个选项。我在一个1.5TB的RAID上有一个1TB的表。SQL Server需要空间进行重新排序和移动。如果空间不足,可以使用DROP INDEX中的“移动到”选项在临时存储上创建表,然后在RAID上重新创建表。您可以将行分块传输,并在传输过程中从源中删除它们。这可能是一个非常缓慢的过程。好吧……为什么创建临时表比删除聚集索引并允许不必要的重新调用要好呢?看起来这将是一样的缓慢和更多的工作。请看这里如何估计新表的大小:嗯,这是我最初的计划,但是删除聚集索引的第二步会导致所有数据移动。我希望以某种方式合并步骤2和步骤3,以避免不必要的数据移动。这是真的吗?我的印象是,数据的物理顺序是由集群键决定的。页面上的数据以正确的顺序存储。页面可以以任何物理顺序存储在磁盘上。您可能希望更新答案以包含此区别。