¿Por qué el salto automático aumenta más de la cantidad de filas insertadas?


11

Estoy muy perturbado por este comportamiento extraño que veo en el auto_incrementvalor registrado en el bidID de una tabla de ofertas después de realizar una inserción masiva utilizando un procedimiento almacenado:

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 ejemplo, si el auto_incrementvalor de bidID es 101 al inicio e inserté 100 filas, el valor final se convierte en 213 en lugar de 201. Sin embargo, los bidID de esas filas insertadas se ejecutan secuencialmente hasta un máximo de 201.

Habiendo comprobado lo siguiente,

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

No tengo idea de por qué está sucediendo. ¿Qué podría estar causando el salto en el auto incrementvalor?


Tablas MyISAM o InnoDB?
Cristian Porta

@CristianPorta, es InnoDB.
Pregunta Desbordamiento

¿Puedes compartir tu show variables like '%innodb_autoinc_lock_mode%';salida?
Cristian Porta

¿Está seguro de que no hay otra conexión / actividad relacionada con la tabla (insertando filas)?
ypercubeᵀᴹ

1
@QuestionOverflow es un buen punto de partida: dev.mysql.com/doc/refman/5.5/en/…
Cristian Porta

Respuestas:


10

Esto no es inusual y hay un par de causas. A veces se debe a optimizaciones que realiza el corredor de consultas para reducir los problemas de contención con el recurso contador, mejorando la eficiencia cuando hay actualizaciones concurrentes en la tabla afectada. A veces se debe a transacciones que se revierten explícitamente (o se revierten implícitamente debido a un error).

Las únicas garantías de una auto_incrementcolumna (o IDENTITYen MSSQL, y los otros nombres por los que pasa el concepto) es que cada valor será único y nunca más pequeño que uno anterior: por lo tanto, puede confiar en los valores para ordenar pero no puede confiar en no tener huecos

Si necesita que los valores de la columna no tengan vacíos, deberá administrar los valores usted mismo, ya sea en otra capa de lógica de negocios o en la base de datos a través de un disparador (tenga cuidado con los posibles problemas de rendimiento con los disparadores), por supuesto si si hace el suyo propio, tendrá que lidiar con todos los problemas de concurrencia / reversión / limpieza después de eliminar / otros que los motores de DB solucionan al permitir huecos).


¿Puede proporcionar algunas referencias donde se discute este comportamiento?
Pregunta Desbordamiento

1
Hay bastantes referencias al asunto aquí, en SO, y en general. Busque "espacios de IDENTIDAD", "espacios de aumento automático", y así sucesivamente, y debería encontrar mucha discusión. Puede agregar su nombre de DBMS para hacer que la búsqueda sea más específica, aunque este es un concepto bastante general, por lo que podría no hacer ninguna diferencia real a menos que esté analizando cómo funciona en detalle.
David Spillett

44
Consulte los detalles de MySQL: Manejo de AUTO_INCREMENT en InnoDB , donde menciona: " Lagunas en los valores de incremento automático para" inserciones masivas " ... Para los modos de bloqueo 1 o 2, pueden producirse lagunas entre sentencias sucesivas porque para las inserciones masivas el número exacto es posible que no se conozcan los valores de incremento automático requeridos por cada instrucción y es posible la sobreestimación ".
ypercubeᵀᴹ

@ypercube, gracias, es muy útil de su parte.
Pregunta Desbordamiento

Consulte también bugs.mysql.com/bug.php?id=34696 .
trss
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.