mysql自增怎么看 mysql数据库自增( 三 )


+----+------+
| id | name |
+----+------+
|1| aaa|
|2| aaa|
|3| aaa|
|4| aaa|
|5| aaa|
+----+------+
5 rows in set (0.00 sec)
[root@localhost][test1] selectAuto_increment from information_schema.tables where table_name='t';
+----------------+
| Auto_increment |
+----------------+
|6 |
+----------------+
【mysql自增怎么看 mysql数据库自增】 1 row in set (0.00 sec)
[root@localhost][test1] rollback;
Query OK, 0 rows affected (0.00 sec)
[root@localhost][test1] selectAuto_increment from information_schema.tables where table_name='t';
+----------------+
| Auto_increment |
+----------------+
|6 |
+----------------+
1 row in set (0.01 sec)
[root@localhost][test1] select * fromt;
+----+------+
| id | name |
+----+------+
|1| aaa|
|2| aaa|
|3| aaa|
|4| aaa|
+----+------+
4 rows in set (0.00 sec)
可以看到,虽然事务回滚了 , 但自增id已经回不到从前啦,唯一键冲突也是这样的,这里就不做测试了 。
在批量插入时(insert select等),也存在空洞的问题 。看下面实验:
[root@localhost][test1] select * fromt;
+----+------+
| id | name |
+----+------+
|1| aaa|
|2| aaa|
|3| aaa|
|4| aaa|
+----+------+
4 rows in set (0.00 sec)
[root@localhost][test1] selectAuto_increment from information_schema.tables where table_name='t';
+----------------+
| Auto_increment |
+----------------+
|5 |
+----------------+
1 row in set (0.00 sec)
[root@localhost][test1] insert intot(name) select name from t;
Query OK, 4 rows affected (0.04 sec)
Records: 4 Duplicates: 0Warnings: 0
[root@localhost][test1] select * fromt;
+----+------+
| id | name |
+----+------+
|1| aaa|
|2| aaa|
|3| aaa|
|4| aaa|
|5| aaa|
|6| aaa|
|7| aaa|
|8| aaa|
+----+------+
8 rows in set (0.00 sec)
[root@localhost][test1] selectAuto_increment from information_schema.tables where table_name='t';
+----------------+
| Auto_increment |
+----------------+
|12 |
+----------------+
1 row in set (0.00 sec)
可以看到,批量插入 , 导致下一个id值不为9了,再插入数据,即产生了空洞,这里是由mysql申请自增值的机制所造成的,MySQL在批量插入时,若一个值申请一个id,效率太慢,影响了批量插入的速度,故mysql采用下面的策略批量申请id 。
1.语句执行过程中,第一次申请自增id,会分配1个;
2.1个用完以后,这个语句第二次申请自增id , 会分配2个;
3.2个用完以后,还是这个语句,第三次申请自增id,会分配4个;
4.依此类推,同一个语句去申请自增id , 每次申请到的自增id个数都是上一次的两倍 。
在对自增列进行操作时,存在着自增锁,mysql的innodb_autoinc_lock_mode参数控制着自增锁的上锁机制 。该参数有0、1、2三种模式:
0:语句执行结束后释放自增锁,MySQL5.0时采用这种模式,并发度较低 。
1:mysql的默认设置 。普通的insert语句申请后立马释放 , insert select、replace insert、load data等批量插入语句要等语句执行结束后才释放,并发读得到提升
2:所有的语句都是申请后立马释放,并发度大大提升!但是在binlog为statement格式时,主从数据会发生不一致 。这一块网上有很多介绍,我不做介绍了 。
在彻底了解了MYSQL的自增机制以后 , 在实际生产中就能灵活避坑,这里建议不要用自增id值去当表的行数,当需要对大表准确统计行数时,可以去count(*)从库,如果业务很依赖大表的准确行数,直接弄个中间表来统计,或者考虑要不要用mysql的innodb来存储数据,这个是需要自己去权衡 。另外对于要求很高的写入性能 , 但写入量又比较大的业务,自增id的使用依然存在热点写入的问题,存在性能瓶颈,这时候可通过分库分表来解决 。

推荐阅读