0

我在数据库中有一个包含 5.8 亿行的表,以及一个笨拙的复合主键。我想更改表的结构以将标识列作为主键。

我正在寻找一些关于在最短的时间内做到这一点的最佳方法的建议。

我们使用的是 SQLServer 2008。

当前表结构:

CREATE TABLE [dbo].[POINTS_EARNED](
[CARD_ID] [int] NOT NULL,
[CYCLE_ID] [int] NOT NULL,
[POINTS_CODE] [int] NOT NULL,
[NO_POINTS] [int] NULL,
[ACCOUNT_ID] [int] NOT NULL,
[CREATED_DATE] [datetime] NULL,
[CREATED_BY] [varchar](20) NULL,
[LAST_MODIFIED_DATE] [datetime] NULL,
[LAST_MODIFIED_BY] [varchar](20) NULL,
[DELETED] [bit] NULL,
 CONSTRAINT [PK_POINTS_EARNED] PRIMARY KEY CLUSTERED 
(
    [CARD_ID] ASC,
    [CYCLE_ID] ASC,
    [POINTS_CODE] ASC,
    [ACCOUNT_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

新结构

CREATE TABLE [dbo].[POINTS_EARNED](
[Points_EARNED_ID] [int] [Identity] Primary Key,
[CARD_ID] [int] NOT NULL,
[CYCLE_ID] [int] NOT NULL,
[POINTS_CODE] [int] NOT NULL,
[NO_POINTS] [int] NULL,
[ACCOUNT_ID] [int] NOT NULL,
[CREATED_DATE] [datetime] NULL,
[CREATED_BY] [varchar](20) NULL,
[LAST_MODIFIED_DATE] [datetime] NULL,
[LAST_MODIFIED_BY] [varchar](20) NULL,
[DELETED] [bit] NULL
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

过去,我们在其他需要重组的表上尝试了 2 种方法:

  1. 在新结构中创建一个空表

  2. 插入新表 SELECT * FROM 旧表

  3. 重命名旧表 oldtable_bak
  4. 将新表重命名为旧表
  5. 将索引等添加到新表

不幸的是,对于大型表,这往往会导致 SSMS 崩溃,因此我们通过将步骤 2 更改为来复制数据:

将旧表中的数据 bcp 到文本文件中,然后从文本文件中将其 bcp 回新表中,这似乎可行,但需要几个小时。

我很想知道是否有更好、更有效的方法来做到这一点。

4

1 回答 1

1

我不确定它是否更有效,但从某种意义上说,以下是“更好”的:

  1. 将现有数据插入新表
  2. 截断现有表
  3. 将表更改为具有标识主键
  4. 插入新表

这更好的原因是因为它保留了触发器、约束、权限和对表的其他引用。这对许多应用程序来说非常方便。

正如您隐含地指出的那样,您可能希望从原始表中删除所有索引并在重新插入数据后添加它们。通常,一次构建索引更有效。

于 2013-09-01T22:49:10.640 回答