最近用MySQL,使用自增列,在執行批量插入時發現不連續現象。這里并沒有洗掉操作,不是刪資料造成的空洞。
后來發現空洞大小和批量大小有些關系,這取決于MySQL生成新的auto_increament_value的方法。
新的自增值會是一個2的n次方的數字。這個數字是大于批量插入資料的最大自增值的2的n次方中最小的那個。
不知道這個行為是不是我特定的MySQL版本造成的,我的版本是5.5.47。
請教大神,是不是有新版本或已經發布的補丁,或者什么設定能改變這個行為,謝了先。
我試了如下一些批量大小發現這個規律,請看下表:
一批插入的資料量,為新資料準備的自增值
============= =================
1,2
2,4
3,4
4,8
5,8
6,8
7,8
8,16
9,16
10,16
11,16
12,16
13,16
14,16
15,16
16,32
下面腳本給有興趣的小伙伴參考。用來產生不連續自增值的腳本:
drop table if exists ttt;
drop table if exists tsource;
create table if not exists ttt (id int auto_increment primary key, name varchar(50));
create table if not exists tsource (name varchar(50));
insert into tsource values
('aaa'),
('bbb'),
('ccc'),
('ddd');
insert into ttt (name)
select name from tsource;
insert into ttt (name) values ('eee');
select * from ttt;
uj5u.com熱心網友回復:
5.7.13 中測驗一樣跳uj5u.com熱心網友回復:
或許可以插入前set AUTO_INCREMENT = max(id)+1 ,因為官方沒有公布這個bug, 改變后不知道會不會影響存盤,uj5u.com熱心網友回復:
insert select陳述句對于自增列會預分配 如果不夠就翻倍所以你插入4條陳述句就分配自增列到8 插入10條陳述句肯定就分配到16 插入20條陳述句就分配到32
uj5u.com熱心網友回復:
是的,這個行為可以理解為“就這么設計的”。畢竟自增的概念和設計原則并不包含連續。想要保證連續的小伙伴只能另想他法了。網上有不少生成連續id的方法,有些還是針對高并發的方案可以參考。
uj5u.com熱心網友回復:
我個人覺得倒不一定影響寸出,但這個方案在考慮并發時需要預先鎖表,不然可能會產生重復的id。
uj5u.com熱心網友回復:
這個測驗結果進一步指向一個結論:MySQL團隊就是這樣設計的,保證連續并不在自增列設計的考慮中。
uj5u.com熱心網友回復:
http://dev.mysql.com/doc/refman/5.7/en/innodb-auto-increment-handling.html#innodb-auto-increment-initialization,后面提到了自增列,但還是想不通為什么這樣設計,你的列子中在首次插入四條資料之后就已經 AUTO_INCREMENT=8了 ,想不通啊想不通uj5u.com熱心網友回復:
其實這只是演示自增列在做批量插入時候行為的示例代碼。我什么也沒設計,如果說MySQL為什么這么設計自增列的行為,我也只能猜測。可能MySQL的這種批量插入自增列的行為是出于性能考慮,不用在批量的每條插入操作中都請求自增量的增加操作。畢竟為保證并發安全這是需要同步處理開銷的。如果預先留出一部分,那么在此之內的批量插入就可以簡單地在執行緒區域+1了,因為其他執行緒會用留出一定空間的新的全域計數值。
uj5u.com熱心網友回復:
其實不然,MYISAM就好好的uj5u.com熱心網友回復:
這里涉及到步長的問題,本次獲取的id,是目前的id數加步長。從來沒有往這個表里寫資料,那么步長就是1,否則步長就是上次插入資料的條數。
比如,現在的最大id是N1,往表里寫入了N2條資料,那么下次寫入資料,就是從N1+N2開始。
uj5u.com熱心網友回復:
https://blog.csdn.net/weixin_39004901/article/details/84871909自增鍵空洞是MySQL的特性導致的,具體跟binlog和innodb_autoinc_lock_mode有關,上述地址有說明。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/63894.html
標籤:MySQL
上一篇:求助mysql建立函式報錯
下一篇:誰能告訴我這是怎么回事啊?
