为什么自动增量跳跃的次数超过插入的行数?


11

auto_increment使用存储过程执行批量插入后,我在Bids表的bidID中记录的值中看到这种奇怪的行为,对此感到非常不安:

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_incrementbidID值为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表?
Cristian Porta 2014年

@CristianPorta,它是InnoDB。
2014年

您可以分享您的show variables like '%innodb_autoinc_lock_mode%';输出吗?
Cristian Porta'3

您确定没有其他与表相关的连接/活动(插入行)吗?
ypercubeᵀᴹ

1
:@QuestionOverflow一个很好的起点dev.mysql.com/doc/refman/5.5/en/...
克里斯蒂安·门

Answers:


10

这并不罕见,原因有两个。有时是由于查询运行程序进行了优化以减少计数器资源的争用问题,从而在对受影响的表进行并发更新时提高了效率。有时是由于事务显式回滚(或由于遇到错误而隐式回滚)引起的。

auto_increment列(或IDENTITYMSSQL,以及该概念所使用的其他名称)的唯一保证是,每个值都是唯一的,并且永远不会比前一个值小:因此,您可以依赖这些值进行排序,但不能依赖他们之间没有差距。

如果您需要该列的值没有任何差值,那么您将需要自己在业务逻辑的另一层或通过触发器在数据库中管理值(当然要小心触发器的潜在性能问题),如果如果您自己动手,则必须应对所有并发性/回滚/删除后清除/其他问题(DB引擎允许间隙来解决)。


您能否在讨论此行为的地方提供一些参考?
问题溢出

1
在SO上,以及一般而言,有很多关于此问题的参考。搜索“ IDENTITY差距”,“ auto_increment差距”,依此类推,您将找到很多讨论。您可以添加DBMS名称以使搜索更加具体,尽管这是一个笼统的概念,因此除非您仔细了解其详细工作原理,否则可能不会有任何实际的不同。
David Spillett 2014年

4
请参阅有关MySQL的详细信息:InnoDB中的 MySQL:AUTO_INCREMENT处理,其中提及:批量插入”的自动增量值之间的间隙...对于锁定模式1或2,连续语句之间可能会出现间隙,因为对于批量插入而言,确切的数目每个语句所需的自动增量值的未知数可能会高估。”
ypercubeᵀᴹ

@ypercube,谢谢,这对您最有帮助。
2014年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.