使用标识列或自行开发的序列表的性能影响

时间:2013-09-16 17:33:26

标签: sql sql-server sql-server-2008

我有一个遗留系统正在使用表来排序数字。该表具有以下定义:

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相比,性能影响(尽可能具体)常规身份栏?这是否具有规模?

我们看到这个表存在很多争议,我想知道表是否已切换到标识列可能会产生(或丢失)哪种类型的性能提升?在这一点上,争论的来源尚不清楚。

(我不知道为什么标识列没有包含在原始设计中 - 这是一个遗留数据库)

2 个答案:

答案 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,这仍然只有一行的问题