Это поведение легко увидеть ниже с установкой по умолчанию для innodb_autoinc_lock_mode
= 1 («последовательный» режим блокировки). Просьба также указать прекрасную справочную страницу под названием AUTO_INCREMENT Handling in InnoDB. Изменение этого значения уменьшит параллелизм и производительность с установкой = 0 для режима блокировки «Tranditional», поскольку он использует блокировку AUTO-INC на уровне таблицы.
Тем не менее, ниже с настройками по умолчанию = 1.
я собираюсь показать вам четыре примеры того, как легко создать пробелы.
Пример 1:
create table x
( id int auto_increment primary key,
someOtherUniqueKey varchar(50) not null,
touched int not null,
unique key(someOtherUniqueKey)
);
insert x(touched,someOtherUniqueKey) values (1,'dog') on duplicate key update touched=touched+1;
insert x(touched,someOtherUniqueKey) values (1,'dog') on duplicate key update touched=touched+1;
insert x(touched,someOtherUniqueKey) values (1,'cat') on duplicate key update touched=touched+1;
select * from x;
+----+--------------------+---------+
| id | someOtherUniqueKey | touched |
+----+--------------------+---------+
| 1 | dog | 2 |
| 3 | cat | 1 |
+----+--------------------+---------+
Разрыв (ID = 2 пропускается) происходит из-за одной из нескольких операций и причудами и нервных подергиваний в INNODB
двигателя. В стандартном высокопроизводительном режиме параллелизма он выполняет распределение интервалов пробелов для различных запросов, отправленных ему. У кого-то есть хорошие причины изменить эту настройку, потому что это влияет на производительность. Похоже на то, что более поздние версии MySQL доставляют вам, и вы отключились из-за Hyper Focusing на пробелы в листах распечаток (и боссы, которые говорят «Почему у нас есть пробелы»).
В случае вставки в обновлении повторяющейся клавиши (IODKU
) он принимает 1 новую строку и выделяет для нее слот. Помните, что параллелизм и ваши сверстники выполняют одни и те же операции, возможно, сотни одновременно. Когда IODKU превращается в Update
, ну, используется использование этой заброшенной и никогда не вставленной строки с id = 2 для вашего подключения и любого другого.
Пример 2:
То же самое происходит во время Insert ... Select From
, как видно на This Answer шахты. В нем я намеренно использую MyISAM
из-за сообщения о подсчетах, min, max, в противном случае отклонение диапазона пробелов будет выделять и не заполнять все. И цифры выглядели бы странно, поскольку этот ответ касался фактических чисел. Таким образом, более старый двигатель (MyISAM
) отлично справился с трудными не-зазорами. Обратите внимание, что в этом ответе я пытался сделать что-то быстро и безопасно, и таблица могла быть преобразована в INNODB
с ALTER TABLE
после факта. Если бы я сделал этот пример в INNODB
для начала, было бы много пробелов (в режиме по умолчанию). Причина, по которой имела бы, создает пробелы в этом ответе, если я использовал INNODB
, был связан с неопределенностью счетчика, механизмом, который движок выбирает для безопасного (неопределенного) распределения диапазона. Двигатель INNODB
знает операцию, естественно, знает, что должен создать безопасный пул AUTO_INCREMENT
id, имеет параллелизм (другие пользователи думают), а пробелы процветают. Это факт. Попробуйте пример 2 с двигателем INNODB
и посмотрите, что вы придумали для min, max и count. Макс не будет равным счетчику.
Примеры 3 и 4:
Существуют различные ситуации, которые вызывают INNODB
Пробелы документированные на сайте Percona, как они натыкаются на более и документировать их. Например, это происходит во время неудачных вставок из-за ограничений внешнего ключа, наблюдаемых в этом 1452 Error image. Или ошибка основного ключа в этом 1062 Error image.
Помните, что промежутки INNODB
являются побочным эффектом производительности системы и безопасного двигателя. Это что-то действительно хочет отключить (производительность, более высокая степень удовлетворенности пользователей, более высокий параллелизм, отсутствие блокировок в сети), ради более жестких диапазонов идентификаторов? Диапазоны, в которых есть дыры при удалении. Я бы предложил не для моих реализаций, а значение по умолчанию с Performance просто отлично.
Он никогда не должен быть критическим, чтобы иметь последовательные идентификаторы, только уникальные ....если вам нужен последовательный, то что-то не так с вашим дизайном –
@MarkBaker Я отредактировал сообщение, чтобы включить мою структуру дизайна таблицы. – youngbobby
Сделайте еще один столбец в таблице, где вы можете вручную добавить целое число, а затем вы можете сохранить этот столбец последовательным, например столбец 'sID', а затем вы можете найти значение MAX, а затем +1 для этого значения для вашей последней вставки. (возможно, вы можете автоматически сделать это в SQL-запросе) – Martin