Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance implications for using an identity column or a homegrown sequence table

I have a legacy system that is using a table for sequencing numbers. The table has the following definition:

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]

This table is functionally equivalent for an identity column.

Here is how the table is used: -A stored procedure runs to get the next value of the id in the table. e.g.,

exec id_proc 'bryans_table', @some_int_value output

I am looking for an expert to answer the following question:

What are the performance implications (as specific as possible) for using a design like this with SQL Server 2008 R2 (currently running in compatibility mode, but plans to use full 2008 R2 at some point in the future) vs. using a regular identity column? Does this scale at all?

We are seeing a lot of contention is this table and I want to know if the tables were switched to identity columns what type of performance gains might be had (or lost)? At this point the source of contention is unclear.

(I do not know why an identity column was not included in the original design -- this is a legacy database)

like image 393
Bryan Crosby Avatar asked Feb 16 '23 06:02

Bryan Crosby


1 Answers

By definition a design like this implies at most one transaction can generate a new sequence for a table (because of the X lock on the record being incremented). In other words, all INSERTs are serialized (no new INSERT can proceed until the first one commits). Performance tanks.

IDENTITY on the other hands is capable of generating the sequences concurrently.

If you're stuck with the sequence table you could generate the new IDs on a separate transaction, requiring a separate connection to the server, and commit immediately the increment. Or generate in batches (increment +1000) and handle the allocated batch in your app code. The later solution works great at alleviating contention. But you loose transactional consistency, the increment occurs on a separate transaction from the INSERT and thus you will see gaps, missing sequences etc. Truth in advertising though: IDENTITY has the same issues (much for the same reasons...)

like image 100
Remus Rusanu Avatar answered Feb 18 '23 09:02

Remus Rusanu