我有一个遗留系统正在使用表来排序数字。该表具有以下定义:
dbo.id_table
(
table_name char(64) NOT NULL,
id_type char(5) NOT NULL,
data_type char(5) NOT NULL,
next_id_number int NOT NULL,
next_id_max char(15) NOT NULL
)
PRIMARY KEY CLUSTERED
(
table_name ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
此表在功能上与标识列等效。
以下是表格的使用方法: - 运行存储过程以获取表中id的下一个值。如,
exec id_proc 'bryans_table', @some_int_value output
我正在寻找专家来回答以下问题:
对于使用SQL Server 2008 R2这样的设计(目前在兼容模式下运行,但计划在未来的某个时间点使用完整的2008 R2)与使用a相比,性能影响(尽可能具体)常规身份栏?这是否具有规模?
我们看到这个表存在很多争议,我想知道表是否已切换到标识列可能会产生(或丢失)哪种类型的性能提升?在这一点上,争论的来源尚不清楚。
(我不知道为什么标识列没有包含在原始设计中 - 这是一个遗留数据库)
答案 0 :(得分:8)
根据定义,这样的设计意味着最多一个事务可以为表生成一个新序列(因为记录上的X锁定递增)。换句话说,所有INSERT都是序列化的(在第一个提交之前,没有新的INSERT可以继续)。高性能坦克。
另一方面,IDENTITY能够同时生成序列。
如果您遇到序列表,可以在单独的事务上生成新ID,需要单独连接到服务器,并立即提交增量。或者批量生成(增量+1000)并在应用代码中处理分配的批次。后一种解决方案可以很好地缓解争用。 但是你失去了事务的一致性,增量发生在与INSERT不同的事务中,因此你会看到缺口,缺失序列等。但广告中的真相:IDENTITY有同样的问题(出于同样的原因) ...)
答案 1 :(得分:0)
您可以使用生成器表来获取序列ID,而不会出现锁争用问题
- 影子表
create table dummy_id (
id int identity not null,
dummy int not null
)
- proc显示用法
create proc dummy_id_gen(@newid int output) as
begin
begin tran
insert dbo.dummy_id (dummy) values (0)
select @newid = scope_identity()
rollback tran
end
- 调用proc来测试它
declare @newid int
exec dummy_id_gen @newid = @newid output
select @newid as newid
对于生成的ID,这仍然只有一行的问题