Мы работаем SQL Server 2012 SP1 x64 (11.0.3000.0)SQL Server: произвольное автоматическое приращение первичного ключа
У меня есть следующая таблица с InvoiceId
поля как автоинкрементные, первичный ключом:
CREATE TABLE Orders(
InvoiceId bigint IDENTITY(1001,1) NOT FOR REPLICATION,
OrderId varchar(8) NOT NULL,
... -- other fields removed for brevity
CONSTRAINT [PK_ORDERS] PRIMARY KEY CLUSTERED (InvoiceId)
ON [PRIMARY],
)
Новые строки вставляются, хотя простой хранимой процедуры, как следующее:
SET XACT_ABORT ON
SET NOCOUNT ON
BEGIN TRANSACTION
INSERT INTO Orders(
OrderId,
... -- other fields removed for brevity
)
VALUES (
@orderId,
...
)
SELECT @newRowId = SCOPE_IDENTITY()
COMMIT TRANSACTION
выше sproc возвращает вновь созданную строку-идентификатор (Orders.InvoiceId
) вызывающему абоненту.
Код работал отлично, с [InvoiceId]
начиная с 1001 и увеличивая на 1 для каждой последовательной вставки.
Наши пользователи вставили около 130 рядов. [InvoiceId]
был на 1130, затем на следующей вставке его значение подскочило до !
Вот скриншот данные:
Я сбит с толку, как к тому, что только что произошло здесь. Почему автоматический счетчик неожиданно пропустил почти 10 000 очков?
Мы используем значение [InvoiceId]
для генерации штрих-кодов, поэтому мы предпочли бы, чтобы значение оставалось в определенном диапазоне, предпочтительно в непрерывной серии.
Я просмотрел документацию T-SQL, но не смог найти что-либо, связанное с моей проблемой. Является ли это обычным поведением (произвольная популяция) поля идентичности?
ОБНОВЛЕНИЕ Благодаря Marting & Aron, я нашел обход. Вот official response от Microsoft:
В SQL Server 2012 реализация имущества идентичности была была изменена для размещения инвестиций в другие функции. В предыдущих версиях SQL Server отслеживание генерации идентичности ссылалось на записи журнала транзакций для каждого генерируемого значения. В SQL Server 2012 мы генерируем идентификационные значения в партиях и регистрируем только максимальное значение партии. Это уменьшает количество и частоту информации, записанной в журнал транзакций, улучшая вставку масштабируемость.
Если требуются те же семантику поколения идентичности, как и предыдущие версии SQL Server есть два доступных опций:
• Используйте флаг трассировки 272 о Это приведет к записи журнала, которые будут созданы для каждого генерируемой идентичности стоимость. Эффективность генерации идентичности может быть вызвана включением этого флага трассировки.
• использовать последовательность генератора с NO CACHE настройки (http://msdn.microsoft.com/en-us/library/ff878091.aspx) O Эта вызовет запись журнала, которые будут созданы для каждого генерируемого значения последовательности . Обратите внимание, что производительность генерации значения последовательности может быть , на которую воздействует NO CACHE.
Пример:
CREATE SEQUENCE s1 AS INT START WITH 1 NO CACHE;
CREATE TABLE t1 (Id INT PRIMARY KEY DEFAULT NEXT VALUE FOR s1, col INT NOT NULL);
'IDENTITY' никогда не гарантируется непрерывным, но есть известная проблема, в 2012 году, где она может внезапно перепрыгнуть оставляя большие пробелы после перезапуска службы. –
Спасибо @MartinSmith! Кажется, это проблема в моем случае. Я помню, как перезагружал машину db до того, как ускорился приращение личности! Как я могу избежать этого? – masroore
Вы не можете избежать этого наверняка, поскольку соприкосновение никогда не гарантировалось, но есть флаг трассировки, который вы можете установить, чтобы получить более медленное (зарегистрированное) поведение 2008 года, или вы можете использовать последовательность с меньшим размером кеша. См. [Обсуждение здесь] (https://connect.microsoft.com/SQLServer/feedback/details/739013/failover-or-restart-results-in-reseed-of-identity) –