【问题标题】:insert into a big table where the PK is not an identity插入到 PK 不是身份的大表中
【发布时间】:2016-05-18 01:13:28
【问题描述】:

我正在将旧数据库中的数据导入新数据库。其中一张表有超过 3000 万行,我必须从 OLD DB 中获取相同的 PK 值。迁移后,我必须开发用于将数据插入该表的存储过程。我的问题是:我应该将 PK(迁移后)设置为身份,还是在插入数据时,找到 PK 的最大值并将其增加 1,然后插入? 如果我应该使用第一种方法,我该怎么做?我尝试通过 Management Studio 执行此操作,但由于超时异常,它总是失败。如果我应该使用第二种方法,它是线程安全的吗?会降低性能吗?

谢谢!

真诚地, 图里克

【问题讨论】:

    标签: sql sql-server database tsql sql-server-2012


    【解决方案1】:

    推荐的方法是在批量加载数据时删除所有索引,包括主键,因为它可以加快加载速度并减少事务日志的负载。但是,您需要确保在加载之前将IDENTITY 属性添加到新表中,并使用SET IDENTITY_INSERT .... ON 允许您插入旧的标识值。

    对于这个例子,让我们假设这是您的目标表:

    CREATE TABLE dbo.YourTable(YourTableId INT IDENTITY(1,1), SomeData INT)
    

    然后您需要使用IDENTITY_INSERT...ON 来确保您可以插入源表中的数据:

    SET IDENTITY_INSERT dbo.YourTable ON
    
    --copy data from source table
    INSERT INTO dbo.YourTable
    (YourTableId, SomeData)
    SELECT 1,1
    UNION
    SELECT 2,2
    

    迁移数据后,您需要再次关闭IDENTITY_INSERT

    SET IDENTITY_INSERT dbo.YourTable OFF
    

    添加主键:

    ALTER TABLE dbo.[YourTable] ADD CONSTRAINT PK_YourTable_YourTableID PRIMARY KEY CLUSTERED (YourTableID) 
    

    然后用RESEED 值等于当前最大 PK 值重新设置主键

    DBCC CHECKIDENT ('[YourTable]', RESEED, 2)
    

    运行此命令后,将插入此记录,YourTableId 的值为 3

    INSERT INTO dbo.YourTable
    SELECT 3
    

    【讨论】:

    • 好的,但是只有当我的表中有一个 Identity 列时 dbcc 才有效。我面临的另一个问题是,将标识添加到具有如此多记录的表中。我怎么解决这个问题?它总是超时。
    • 对不起,当您的答案较短时(初始版本),我添加了评论。
    猜你喜欢
    • 2019-06-25
    • 1970-01-01
    • 2014-04-23
    • 1970-01-01
    • 2016-12-16
    • 2012-06-20
    • 2012-01-15
    • 1970-01-01
    • 2020-02-12
    相关资源
    最近更新 更多