Sql 向现有表中添加自动递增的列
鉴于: 我们有一个名为Events的表,目前包含大约1亿行:Sql 向现有表中添加自动递增的列,sql,sql-server,tsql,auto-increment,Sql,Sql Server,Tsql,Auto Increment,鉴于: 我们有一个名为Events的表,目前包含大约1亿行: CREATE TABLE [dbo].[Events]( [Id] [uniqueidentifier] NOT NULL, [AggregateId] [uniqueidentifier] NOT NULL, [SourceType] [varchar](500) NOT NULL, [SourceId] [nvarchar](200) NOT NULL, [Timestamp] [datet
CREATE TABLE [dbo].[Events](
[Id] [uniqueidentifier] NOT NULL,
[AggregateId] [uniqueidentifier] NOT NULL,
[SourceType] [varchar](500) NOT NULL,
[SourceId] [nvarchar](200) NOT NULL,
[Timestamp] [datetimeoffset](4) NOT NULL,
[SerializedJson] [nvarchar](max) NOT NULL,
[EventDataType] [varchar](500) NOT NULL,
CONSTRAINT [PK_tblCepEvent_Id] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [UData]
) ON [UData] TEXTIMAGE_ON [UData]
GO
ALTER TABLE [dbo].[tblCepEvent] ADD CONSTRAINT [DF_tblCepEvent_Id] DEFAULT (newid()) FOR [Id]
GO
我们在SourceId列上还有一个非聚集索引
CREATE NONCLUSTERED INDEX [IX_tblCepEvent_SourceId] ON [dbo].[tblCepEvent] ([SourceId] ASC)
GO
期望:
我们希望添加一个新的整数列,该列包含与现有行的时间戳列顺序相同的自动递增值。背后的理念;我们正在处理大量数据,其中一些数据具有相同的时间戳值,因此我们希望能够按照插入的顺序对它们进行排序
尝试:
为了使自动递增的值与时间戳列的顺序相同,我删除了所有现有索引,然后在时间戳列上创建了一个升序聚集索引
-- 1 - drop primary key constraint
ALTER TABLE dbo.tblCepEvent DROP CONSTRAINT [PK_tblCepEvent_Id]
GO
-- 2- drop index on SourceId
DROP INDEX [IX_tblCepEvent_SourceId] ON dbo.tblCepEvent
GO
-- 3 - create a temporary asc clustered index on timestamp column
CREATE CLUSTERED INDEX [CIX_tblCepEvent_Timestamp] ON dbo.tblCepEvent ([Timestamp] ASC)
GO
然后我尝试创建新的专栏
-- 4 - create auto incremented column
ALTER TABLE dbo.tblCepEvent ADD OrderIndex BIGINT IDENTITY(1, 1) NOT NULL
GO
创建此列之后,我计划删除Timestamp列上的临时索引,然后返回并在SourceId列上创建主键和非聚集索引。
但不知何故,出现了一些错误,查询锁定了数据库,因此我不得不取消查询
在最后一次尝试之前,我在一组较小的数据(100万行)上测试了这种方法,并观察到它可以完成这项工作。
现在我的问题是:对于一个有超过1亿行的表,这是实现预期结果的好方法吗?您有什么建议可以更有效、更稳健地满足这一期望吗?不要乱动删除和添加索引,这并不能保证满足您的要求。添加不带
标识的整数列
。通过row\u number
使用所需的顺序将其填充为序列号,然后使用序列而不是identity
来获取未来的新值,或者使用ALTER TABLE。。。切换
方法使列成为仅元数据更改的标识
列如果您在SSMS中尝试了相同的操作并检查了生成的脚本,您会看到它使用标识创建了一个新表,将现有表中的所有行插入其中,然后重命名表。这对于大型表来说更具可伸缩性(也更安全)。使用altertable。。。SWITCH
是一种更快的方法,它通过将一个表的数据页交换为另一个表来实现。这两个表必须具有相同的模式,但在您的示例中,不能依赖标识值来保持SELECT查询的顺序。出于性能原因,标识值是预先计算、缓存和批量分配的。当移动100米行时,所有这些机制都会起作用。您必须使用ROW_NUMBER()OVER(ORDER BY timestamp)
在插入过程中生成ID值,并在插入后添加IDENTITY
约束。不要乱丢和添加索引,这也不能保证满足您的要求。添加不带标识的整数列
。通过row\u number
使用所需的顺序将其填充为序列号,然后使用序列而不是identity
来获取未来的新值,或者使用ALTER TABLE。。。切换
方法使列成为仅元数据更改的标识
列如果您在SSMS中尝试了相同的操作并检查了生成的脚本,您会看到它使用标识创建了一个新表,将现有表中的所有行插入其中,然后重命名表。这对于大型表来说更具可伸缩性(也更安全)。使用altertable。。。SWITCH
是一种更快的方法,它通过将一个表的数据页交换为另一个表来实现。这两个表必须具有相同的模式,但在您的示例中,不能依赖标识值来保持SELECT查询的顺序。出于性能原因,标识值是预先计算、缓存和批量分配的。当移动100米行时,所有这些机制都会起作用。您必须使用ROW\u NUMBER()OVER(按时间戳排序)
在插入期间生成ID值,然后添加IDENTITY
约束