SQL Значение столбца ID скачет 10000 раз - PullRequest
0 голосов
/ 10 апреля 2020

Индекс столбца ID скачет 10000 раз.

Например:

С индекс :

  • 5 переходит на 10006

  • и продолжается 10007, 10008, 10009

  • и затем переходит к 20003, 20004. ...

Как я могу исправить значения идентификаторов и снова упорядочить их, как раньше?

Также я нашел кое-что о функции Reseed, но я делаю не знаете что это такое и как им пользоваться?

Ответы [ 3 ]

3 голосов
/ 10 апреля 2020

Я предполагаю, что вы используете столбец идентификаторов:

ID INT NOT NULL IDENTITY(1,1)

Нет гарантии, что это останется в последовательности. Это было раздражающим, когда это сначала стало более очевидным (это, казалось, не случалось в более старых версиях SQL Server, но очевидно могло произойти), но также всегда было разработано. Пропуск стал очень очевидным, когда 2012 (?) Был выпущен. Я полагаю, вы должны использовать ПОСЛЕДОВАТЕЛЬНОСТЬ сейчас, если необходимо поддерживать постоянную последовательность - например, номера счетов:

https://dba.stackexchange.com/questions/62151/what-could-cause-an-auto-increment-primary-key-to-skip-numbers

https://docs.microsoft.com/en-us/sql/t-sql/statements/create-sequence-transact-sql?view=sql-server-ver15

Может также показаться, что вы пропускаете, если вы выполняете INSERT, и она терпит неудачу, но обычно это пропускает только 1. Это всегда происходило и задумано - вам нужно заново идентифицировать себя, чтобы преодолеть это. Что-то вроде:

DBCC CHECKIDENT ("dbo.MyTable", RESEED, 10)

Создаст следующий идентификационный номер 11. При условии, что другой пропуск также не произойдет.

РЕДАКТИРОВАТЬ: В отношении повторного выравнивания существующих записей я не DB Expert, но я сделал это на днях на столе, используя довольно элементарный подход - но это всего лишь маленький стол - возможно, есть лучший способ сделать это:

BEGIN TRAN

--CREATE TEMP TABLE
DECLARE @Tooltip TABLE
(
    [TooltipId] INT NOT NULL,
    [TooltipKey] NVARCHAR(100) NOT NULL,
    [Name] NVARCHAR(255) NOT NULL
)

--INSERT EXISTING INTO TEMP TABLE
INSERT INTO @Tooltip (TooltipKey, Name )
SELECT TooltipKey, Name
FROM dbo.Tooltip
ORDER BY TooltipId


--CLEAR ACTUAL TABLE
TRUNCATE TABLE dbo.Tooltip

--RESET IDENTITY TO 1
DBCC CHECKIDENT ("dbo.Tooltip", RESEED, 1)

--REINSERT FROM TEMP TABLE INTO ACTUAL TABLE
INSERT INTO dbo.Tooltip (TooltipKey, Name )
SELECT TooltipKey, Name
FROM @Tooltip
ORDER BY TooltipId

--TEST OUTPUT
SELECT * FROM dbo.Tooltip

--DO THIS FOR TESTING
ROLLBACK TRAN

--DO THIS WHEN YOU'RE CERTAIN YOU WANT TO PERFORM THE ACTION
--COMMIT TRAN

Принимая во внимание, что если у вас есть внешние ключи или другие ссылки, усечение не будет работать, и вам придется делать что-то более сложное. Особенно, если у вас есть внешние ключи, ссылающиеся на ваши существующие неправильные идентификаторы

1 голос
/ 10 апреля 2020

У вас были большие удаления?

Удаление не сбрасывает идентификатор, поэтому, если у вас были строки 1-10000, а затем все они удалены, идентификатор все равно продолжится с 10001, когда вы добавите новая строка.

Усечение сбрасывает идентичность, но всегда УДАЛЯЕТ ВСЕ СТРОКИ без регистрации.

Вы также можете использовать функцию повторного заполнения для сброса идентичности, но это не поможет в этом случае, так как вы медленно увеличивать обратно в идентификаторы, используемые существующими данными.

1 голос
/ 10 апреля 2020

Это не проблема. Это функция производительности SQL Server.

SQL Сервер предназначен для обработки множества одновременных транзакций - например, десятки или сотни вставок в секунду. Это может быть сделано в системах с несколькими процессорами.

В такой среде «добавление только 1» к максимуму может привести к большим накладным расходам - ​​все разные процессоры должны договориться о том, что такое максимум. Это включает в себя сложную блокировку или последовательность транзакций, что замедляет процесс.

Чтобы избежать узких мест в производительности, SQL Сервер иногда предварительно выделяет значения идентификаторов. Это может привести к пробелам, если числа не используются.

Если вам не нравится эта функция, вы можете обойти ее, используя последовательность и триггер для присвоения значения. Просто имейте в виду, что альтернативные подходы влияют на производительность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...