Perché l'incremento automatico salta di oltre il numero di righe inserite?


11

Sono molto turbato da questo strano comportamento che sto vedendo nel auto_incrementvalore registrato nel bidID di una tabella di offerte dopo aver eseguito l'inserimento di massa utilizzando una procedura memorizzata:

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;

Ad esempio, se il auto_incrementvalore bidID è 101 all'inizio e ho inserito 100 righe, il valore finale diventa 213 anziché 201. Tuttavia, gli bidID di tali righe inserite vengono eseguiti in sequenza fino a un massimo di 201.

Dopo aver verificato quanto segue,

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

Non ho idea del perché stia accadendo. Cosa potrebbe causare il salto nel auto incrementvalore?


Tabelle MyISAM o InnoDB?
Cristian Porta

@CristianPorta, è InnoDB.
Domanda Overflow

Puoi condividere il tuo show variables like '%innodb_autoinc_lock_mode%';output?
Cristian Porta

Sei sicuro che non ci siano altre connessioni / attività correlate alla tabella (inserimento di righe)?
ypercubeᵀᴹ

1
@QuestionOverflow di un buon punto di partenza: dev.mysql.com/doc/refman/5.5/en/…
Cristian Porta

Risposte:


10

Questo non è insolito e ci sono un paio di cause. A volte è dovuto alle ottimizzazioni apportate dal Runner query per ridurre i problemi di contesa con la risorsa contatore, migliorando l'efficienza quando sono presenti aggiornamenti simultanei alla tabella interessata. A volte è dovuto a transazioni che sono state esplicitamente ripristinate (o implicitamente ripristinate a causa di un errore).

L'unica garanzia da una auto_incrementcolonna (o IDENTITYin MSSQL e gli altri nomi che il concetto passa) è che ogni valore sarà unico e mai più piccolo di uno precedente: quindi puoi fare affidamento sui valori per ordinare ma non puoi fare affidamento loro di non avere lacune.

Se hai bisogno che i valori della colonna non abbiano alcuna lacuna, dovrai gestire i valori da solo, in un altro livello di logica aziendale o nel DB tramite un trigger (fai attenzione però ai potenziali problemi di prestazioni con i trigger), ovviamente se fai il tuo dovere dovrai affrontare tutti i problemi di concorrenza / rollback / cleanup-after-delete / altri che i motori DB risolvono consentendo spazi vuoti).


Potete fornire alcuni riferimenti in cui questo comportamento è in discussione?
Domanda Overflow

1
Ci sono alcuni riferimenti all'argomento qui, su SO e in generale. Cerca "IDENTITY gap", "auto_increment gap" e così via, e dovresti trovare molte discussioni. Potresti aggiungere il tuo nome DBMS per rendere la ricerca più specifica, anche se questo è un concetto abbastanza generale, quindi potrebbe non fare alcuna differenza reale a meno che tu non stia osservando come funziona in dettaglio.
David Spillett,

4
Vedi i dettagli di MySQL: Gestione AUTO_INCREMENT in InnoDB , dove menziona: " Lacune nei valori di autoincremento per" inserti in blocco " ... Per le modalità di blocco 1 o 2, possono verificarsi spazi vuoti tra istruzioni successive perché per inserimenti in blocco il numero esatto dei valori di incremento automatico richiesti da ciascuna istruzione potrebbe non essere noto ed è possibile una sovrastima. "
ypercubeᵀᴹ

@ypercube, grazie, è molto utile per te.
Domanda Overflow

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.