Pourquoi l'incrémentation automatique saute-t-elle de plus que le nombre de lignes insérées?


11

Je suis très perturbé par ce comportement étrange que je constate dans la auto_incrementvaleur enregistrée dans le bidID d'une table Bids après avoir effectué une insertion en bloc à l'aide d'une procédure stockée:

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;

Par exemple, si la auto_incrementvaleur bidID est 101 au début et que j'ai inséré 100 lignes, la valeur de fin devient 213 au lieu de 201. Cependant, les bidID de ces lignes insérées s'exécutent séquentiellement jusqu'à un maximum de 201.

Après avoir vérifié les éléments suivants,

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

Je ne sais pas pourquoi cela se produit. Qu'est-ce qui pourrait provoquer le saut de la auto incrementvaleur?


Tables MyISAM ou InnoDB?
Cristian Porta

@CristianPorta, c'est InnoDB.
Débordement de questions

Pouvez-vous partager votre show variables like '%innodb_autoinc_lock_mode%';sortie?
Cristian Porta

Êtes-vous sûr qu'il n'y a aucune autre connexion / activité liée à la table (insertion de lignes)?
ypercubeᵀᴹ

1
@QuestionOverflow un bon point de départ: dev.mysql.com/doc/refman/5.5/en/…
Cristian Porta

Réponses:


10

Ce n'est pas inhabituel et il y a deux ou trois causes. Parfois, cela est dû aux optimisations effectuées par le programme d'exécution de requêtes pour réduire les problèmes de contention avec la ressource de compteur, améliorant ainsi l'efficacité en cas de mises à jour simultanées de la table affectée. Parfois, cela est dû à des transactions qui ont été annulées explicitement (ou annulées implicitement en raison d'une erreur).

La seule garantie d'une auto_incrementcolonne (ou IDENTITYen MSSQL, et les autres noms utilisés par le concept) est que chaque valeur sera unique et jamais plus petite qu'une précédente: vous pouvez donc vous fier aux valeurs de commande, mais vous ne pouvez pas vous fier à pour qu'ils n'aient pas de lacunes.

Si vous avez besoin que les valeurs de la colonne ne comportent aucune lacune, vous devrez gérer les valeurs vous-même, soit dans une autre couche de logique métier, soit dans la base de données via un déclencheur (faites cependant attention aux problèmes de performances potentiels avec les déclencheurs), bien sûr si vous roulez vous-même, vous devrez faire face à tous les problèmes de concurrence / restauration / nettoyage après suppression / autres que les moteurs de base de données contournent en autorisant des écarts).


Pouvez-vous fournir des références où ce comportement est discuté?
Débordement de questions

1
Il y a pas mal de références à la question ici, sur SO, et en général. Recherchez «Lacunes IDENTITY», «Lacunes auto_increment», etc., et vous devriez trouver de nombreuses discussions. Vous pouvez ajouter votre nom de SGBD pour rendre la recherche plus spécifique, bien qu'il s'agisse d'un concept assez général, qui ne fera aucune différence réelle, sauf si vous regardez sous le capot comment il fonctionne en détail.
David Spillett

4
Voir les détails de MySQL: AUTO_INCREMENT Manipulation dans InnoDB , où il mentionne: " Lacunes dans les valeurs d'incrémentation automatique pour les" insertions groupées " ... Pour les modes de verrouillage 1 ou 2, des écarts peuvent se produire entre les instructions successives car pour les insertions groupées le nombre exact des valeurs d'auto-incrémentation requises par chaque instruction peuvent ne pas être connues et une surestimation est possible. "
ypercubeᵀᴹ

@ypercube, merci, c'est le plus utile de vous.
Débordement de questions

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.