在SQL Server中更改大表的主键的最佳方法

时间:2013-09-01 22:00:23

标签: sql-server bcp

我在数据库中有一个表,其中包含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]

过去,我们已尝试过两种方法在需要重组的其他表上执行此操作:

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

  2. INSERT INTO Newtable SELECT * FROM Oldtable

  3. 重命名旧表oldtable_bak
  4. 将新表重命名为旧表
  5. 将索引等添加到新表
  6. 不幸的是,对于大型表,这往往会导致SSMS崩溃,因此我们通过将步骤2更改为:

    来复制数据

    将bcp数据从旧表中导出成文本文件,然后将bcp从文本文件返回到新表中,这似乎有效,但需要几个小时。

    我很想知道是否有更好,更有效的方法。

1 个答案:

答案 0 :(得分:1)

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

  1. 将现有数据插入新表格
  2. 截断现有表格
  3. 将表更改为具有标识主键
  4. 插入新表格
  5. 这更好的原因是因为它保留了对表的触发器,约束,权限和其他引用。这对许多应用程序来说都非常方便。

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