Estou muito incomodado com esse comportamento estranho que estou vendo no auto_increment
valor registrado no bidID de uma tabela de Bids após realizar a inserção em massa usando um procedimento armazenado:
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;
Por exemplo, se o auto_increment
valor bidID for 101 no início e eu inserir 100 linhas, o valor final se tornará 213 em vez de 201. No entanto, os bidIDs dessas linhas inseridas são executados sequencialmente até um máximo de 201.
Verificando o seguinte,
SHOW VARIABLES LIKE 'auto_inc%';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| auto_increment_increment | 1 |
| auto_increment_offset | 1 |
+--------------------------+-------+
Eu não tenho idéia por que isso está acontecendo. O que poderia estar causando o salto no auto increment
valor?
Isso não é incomum e existem algumas causas. Às vezes, é devido a otimizações que o executor de consultas faz para reduzir problemas de contenção com o recurso de contador, melhorando a eficiência quando há atualizações simultâneas na tabela afetada. Às vezes, é devido a transações que foram revertidas explicitamente (ou revertidas implicitamente devido ao encontro de um erro).
As únicas garantias de uma
auto_increment
coluna (ouIDENTITY
em MSSQL, e os outros nomes pelos quais o conceito passa) é que cada valor será único e nunca menor que o anterior: então você pode confiar nos valores para ordenar, mas não pode confiar em que não tenham lacunas.Se você precisar que os valores da coluna não tenham lacunas, precisará gerenciar os valores você mesmo, em outra camada de lógica de negócios ou no banco de dados por meio de um gatilho (no entanto, tenha cuidado com possíveis problemas de desempenho com gatilhos), é claro se você vai ter que lidar com todos os problemas de simultaneidade/reversão/limpeza-após-exclusão/outros que os mecanismos de banco de dados contornam, permitindo lacunas).
Pode ter várias causas:
Verifique se o valor de auto_increment na própria tabela tem o próximo valor mais alto.
Lembre-se de que, se você tiver transações em que você INSERT uma linha e reverta a transação, esse valor de auto_increment será ignorado.
innodb_autoinc_lock_mode=1
(consecutiva) ouinnodb_autoinc_lock_mode=2
(intercalada). Nesse caso, instruções INSERT únicas e instruções INSERT em massa podem ser executadas umas pelas outras. Definidoinnodb_autoinc_lock_mode=0
para garantir que as instruções sejam executadas em ordem.Todas as citações são de: https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html :