Почему автоматическое увеличение скачков больше, чем количество вставленных строк?

11

Меня очень беспокоит это странное поведение, которое я вижу в auto_incrementзначении, записанном в bidID таблицы Bids после выполнения массовой вставки с использованием хранимой процедуры:

INSERT INTO Bids (itemID, buyerID, bidPrice)
 SELECT itemID, rand_id(sellerID, user_last_id), FLOOR((1 + RAND())*askPrice)
 FROM Items
 WHERE closing BETWEEN NOW() AND NOW() + INTERVAL 1 WEEK ORDER BY RAND() LIMIT total_rows;

Например, если auto_incrementзначение bidID равняется 101 в начале, и я вставил 100 строк, конечное значение становится 213 вместо 201. Однако, идентификаторы bidID этих вставленных строк последовательно работают максимум до 201.

Проверив следующее,

SHOW VARIABLES LIKE 'auto_inc%';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 1     |
| auto_increment_offset    | 1     |
+--------------------------+-------+

Я понятия не имею, почему это происходит. Что может быть причиной скачка auto incrementзначения?

Вопрос переполнен
источник
MyISAM или InnoDB таблицы?
Кристиан Порта
@CristianPorta, это InnoDB.
Переполнение вопроса
Можете ли вы поделиться своим show variables like '%innodb_autoinc_lock_mode%';выходом?
Кристиан Порта
Вы уверены, что нет другой связи / деятельности, связанной с таблицей (вставка строк)?
ypercubeᵀᴹ
1
@QuestionOverflow хорошая отправная точка: dev.mysql.com/doc/refman/5.5/en/…
Кристиан Порта

Ответы:

10

Это не является необычным, и есть несколько причин. Иногда это происходит из-за оптимизаций, выполняемых обработчиком запросов, чтобы уменьшить проблемы конкуренции с ресурсом счетчика, повышая эффективность при одновременном обновлении уязвимой таблицы. Иногда это происходит из-за транзакций, которые были откатаны явным образом (или откатаны неявно из-за ошибки).

Единственная гарантия от auto_incrementстолбца (или IDENTITYв MSSQL, и других именах, которые использует концепция) состоит в том, что каждое значение будет уникальным и никогда не будет меньше предыдущего: так что вы можете положиться на значения для упорядочения, но вы не можете полагаться на у них не должно быть пробелов.

Если вам нужно, чтобы значения столбца вообще не имели пропусков, вам нужно будет управлять значениями самостоятельно, либо на другом уровне бизнес-логики, либо в БД с помощью триггера (хотя будьте осторожны с потенциальными проблемами производительности с триггерами), конечно вы делаете свой собственный, вам придется столкнуться со всеми проблемами параллелизма / отката / очистки после удаления / другими проблемами, с которыми работают механизмы БД, допуская пропуски).

Дэвид Спиллетт
источник
Можете ли вы предоставить некоторые ссылки, где это поведение обсуждается?
Переполнение вопроса
1
Здесь довольно много ссылок на этот вопрос, на SO и вообще. Ищите «Пробелы IDENTITY», «Пробелы auto_increment» и т. Д., И вы должны найти множество обсуждений. Вы можете добавить свое имя СУБД, чтобы сделать поиск более конкретным, хотя это довольно общая концепция, которая может не иметь никакого реального значения, если вы не заглянете в подробности, как она работает.
Дэвид Спиллетт
4
Смотрите подробности для MySQL: Обработка AUTO_INCREMENT в InnoDB , где упоминается: « Пробелы в значениях автоинкремента для« массовых вставок » ... Для режимов блокировки 1 или 2 между последовательными операторами могут возникать пропуски, потому что для массовых вставок точное число значения автоинкремента, требуемые каждым оператором, могут быть неизвестны, и возможна переоценка. "
ypercubeᵀᴹ
@ypercube, спасибо, это самый полезный из вас.
Вопрос переполнен
Также см. Bugs.mysql.com/bug.php?id=34696 .
TRSS