6

我有一个表,它在两列上有一个聚集索引 - 表的主键。定义如下:

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 聚集索引,然后添加新的聚集索引,然后添加非聚集主键索引,但我了解到删除现有聚集索引会导致表数据重新排序(请参阅此处的答案What当我在 SQL 2005 中删除集群主键时发生),我认为这不是必需的。该表正在敲 1 TB,所以我真的想避免任何不必要的重新排序。

我的问题是,从现有结构到所需结构的最佳方式是什么?

编辑:只是想澄清一下。该表为 1TB,不幸的是我没有空间来创建临时表。如果有办法在不创建临时表的情况下做到这一点,请告诉我。

4

4 回答 4

11

This isn't a complete answer to your question, but make sure that if you have any other indexes on the table that you drop those first. Otherwise SQL Server will have to rebuild them all when you remove the clustered index then rebuild them all again when you add back a new clustered index. The usual steps are:

  1. Remove all non-clustered indexes
  2. Remove clustered index
  3. Add new clustered index
  4. Add back all non-clustered indexes
于 2009-04-01T14:51:36.290 回答
8

If your table is getting up to 1 TB in size and probably has LOTS of rows in it, I would strongly recommend NOT making the clustered index that much fatter!

First of all, dropping and recreating the clustered index will shuffle around ALL your data at least once - that alone will take ages.

Secondly, the big compound clustered index you're trying to create will significantly increase the size of all your non-clustered indices (since they contain the whole clustered index value on each leaf node, for the bookmark lookups).

The question is more: why are you trying to do this?? Couldn't you just add another non-clustered index with those columns, to potentially cover your queries? Why does this have to be the clustered index?? I don't see any advantage in that....

For more information on indexing and especially the clustered index debate, see Kimberly Tripp's blog on SQL Server indexes - very helpful!

Marc

于 2009-04-02T05:32:40.120 回答
4
  1. 创建一个新表:

    CREATE TABLE newtable (colA INT, colB INT)
    
    • 将旧表中的所有值插入到新表中:

      插入新表 SELECT * FROM 表

    • 删除旧表:

      DROP TABLE 表

    • 将新表重命名为旧表

      EXEC sp_rename 'newtable', 'table'

    • 建立索引:

      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]

于 2009-04-01T14:33:49.873 回答
-3

Clustered indexes don't actually change the physical order of the data being stored in the table it self. It hasn't been this way since SQL 6.5.

The data on the pages is stored in the correct order. The pages can be stored on the disk in any physical order.

于 2009-04-06T08:04:38.263 回答