数据库
首页 > 数据库> > mysql-具有较大的自动增量值的行是否可以比具有较小的一行的行出现得更快?

mysql-具有较大的自动增量值的行是否可以比具有较小的一行的行出现得更快?

作者:互联网

以下情况可能吗?

MySQL版本5.6.15

CREATE TABLE my_table (
    id int NOT NULL AUTO_INCREMENT.
    data1 int,
    data2 timestamp,
    PRIMARY KEY (id)
) ENGINE=InnoDB;

innodb_autoinc_lock_mode = 1

AUTO_INCREMENT = 101

> 0 ms:运行查询A:插入到my_table(data1,data2)值(101,FROM_TIMESTAMP(1418501101)),(102,FROM_TIMESTAMP(1418501102)),.. [总共200个值] ..,(300, FROM_TIMESTAMP(1418501300));
> 500 ms:运行查询B:INSERT INTO my_table(data1,data2)VALUES(301,FROM_TIMESTAMP(1418501301));
> 505 ms:查询B完成.该行的ID为301.
> 1000毫秒:从my_table中选择ID,其中id> = 300; —将返回一行(id = 301).
> 1200 ms:查询A完成.这些行的id为101到id为300.
> 1500毫秒:从my_table中选择ID,其中ID> == 300; —将返回两行(id = 300,id = 301).

换句话说,是否可以选择id = 301的行早于选择id = 300的行?

以及如何避免呢?

解决方法:

为什么查询A要花一秒钟以上的时间来运行? !是的,您所看到的正是我所期望的行为.

在插入新行时立即保留主键101到300.这需要几毫秒的时间.然后,它花费超过1秒钟的时间来重建索引,并在运行所有查询的过程中完成了所有操作,并使用下一个可用的auto_increment:301插入了新行.

正如Alin Purcaru所说的那样,您可以通过更改锁定模式来避免此特定问题,但是它将引起性能问题(查询B而不是在5毫秒内执行,而是需要700毫秒来执行.

在高负载情况下,问题成倍恶化,最终您将看到“连接过多”错误,有效地使整个数据库脱机.

另外,在其他少数情况下,auto_increment可以给出“乱序”的增量,这不能通过锁定解决.

我个人认为最好的选择是使用UUID代替auto_increment作为主键,然后使用一个timestamp列(以微秒为单位的两倍)来确定将哪些顺序行插入到数据库中.

标签:innodb,auto-increment,mysql
来源: https://codeday.me/bug/20191120/2047975.html