You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何将主键从INT改为BIGINT时,新建表比修改列更高效?

主键列从INT改BIGINT:为何ALTER方案比建新表插入慢4倍?

我有一张主键为INT类型的表,需要将其修改为BIGINT类型。测试两种常见解决方案后,执行速度的差异完全出乎意料。

我原本认为下面的操作会非常高效:

ALTER TABLE tablename DROP CONSTRAINT constraint_name
ALTER TABLE tablename alter column Id bigint not null
ALTER TABLE tablename
ADD CONSTRAINT constraint_name
PRIMARY KEY NONCLUSTERED ([Id] ASC) WITH (
    PAD_INDEX = OFF
    , STATISTICS_NORECOMPUTE = OFF
    , SORT_IN_TEMPDB = OFF
    , IGNORE_DUP_KEY = OFF
    , ONLINE = OFF
    , ALLOW_ROW_LOCKS = ON
    , ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

但实际测试发现,下面的操作速度居然是上面方法的4倍:

Select * Into newtable From tablename where 1=0

Alter Table newtable
alter column Id bigint not null

set identity_insert newtable ON

insert into newtable
(Id, all_the_other_column_names)
Select *
From tablename

--rename tables properly 

看到有解释说:MS SQL Server采用逐行存储数据的方式,若修改第一列的大小,所有其他列的数据都需要移位,给更大的BIGINT列腾出空间;而向已设置好正确数据类型的空表中插入数据,复制过程比移位其他列更高效。

请问这真的是导致两种方案效率差异的核心原因吗?

测试表生成脚本

-- Declare variables
DECLARE @RowCount INT = 10; -- Adjust this variable to control the number of rows
DECLARE @Counter INT = 1;

-- Create a temporary table
CREATE TABLE RandomTable (
    ID INT PRIMARY KEY,
    RandomString NVARCHAR(10)
);

-- Loop to insert rows into the table
WHILE @Counter <= @RowCount
BEGIN
    -- Insert random data into the table
    INSERT INTO RandomTable (ID, RandomString)
    VALUES (
        @Counter,
        LEFT(CAST(NEWID() AS NVARCHAR(36)), 10)
    );

    -- Increment counter
    SET @Counter = @Counter + 1;
END

-- Display the contents of the table
SELECT * FROM RandomTable;

查看主键约束名称脚本

SELECT name  
FROM sys.key_constraints  
WHERE type = 'PK' 
and name like '%Random%'

内容的提问来源于stack exchange,提问作者Merlin Nestler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 23:31:29