ทำไมการเพิ่มอัตโนมัติถึงกระโดดเกินจำนวนแถวที่แทรกเข้าไป


11

ฉันรู้สึกยุ่งเหยิงมากจากพฤติกรรมแปลก ๆ นี้ที่ฉันเห็นในauto_incrementค่าที่บันทึกไว้ใน 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_incrementค่า bidID คือ 101 เมื่อเริ่มต้นและฉันแทรก 100 แถวค่าสิ้นสุดจะกลายเป็น 213 แทนที่จะเป็น 201 อย่างไรก็ตาม BidIDs ของแถวที่แทรกเหล่านั้นจะทำงานตามลำดับสูงสุด 201

มีการตรวจสอบดังต่อไปนี้

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

ฉันไม่รู้ว่าทำไมมันถึงเกิดขึ้น สิ่งที่อาจทำให้เกิดการกระโดดในauto incrementค่า?


ตาราง MyISAM หรือ InnoDB?
Cristian Porta

@CristianPorta เป็น InnoDB
คำถามล้น

คุณสามารถแบ่งปันshow variables like '%innodb_autoinc_lock_mode%';ผลผลิตของคุณ?
Cristian Porta

คุณแน่ใจหรือไม่ว่าไม่มีการเชื่อมต่อ / กิจกรรมอื่น ๆ ที่เกี่ยวข้องกับตาราง (การแทรกแถว)
ypercubeᵀᴹ

1
@QuestionOverflow จุดเริ่มต้นที่ดี: dev.mysql.com/doc/refman/5.5/en/…
Cristian Porta

คำตอบ:


10

นี่ไม่ใช่เรื่องแปลกและมีสาเหตุสองประการ บางครั้งอาจเกิดจากการปรับให้เหมาะสมที่ตัวเรียกใช้คิวรีทำเพื่อลดปัญหาความขัดแย้งกับตัวนับทรัพยากรซึ่งจะปรับปรุงประสิทธิภาพเมื่อมีการอัพเดตพร้อมกันในตารางที่ได้รับผลกระทบ บางครั้งมันเป็นเพราะการทำธุรกรรมที่มีการย้อนกลับอย่างชัดเจน (หรือย้อนกลับโดยปริยายเนื่องจากพบข้อผิดพลาด)

การรับประกันเดียวจากauto_incrementคอลัมน์ (หรือIDENTITYใน MSSQL และชื่ออื่น ๆ ที่เป็นไปตามแนวคิด) คือแต่ละค่าจะไม่ซ้ำกันและไม่เล็กกว่าค่าก่อนหน้า: ดังนั้นคุณสามารถพึ่งพาค่าสำหรับการสั่งซื้อ แต่คุณไม่สามารถพึ่งพาได้ พวกเขาจะไม่มีช่องว่าง

หากคุณต้องการค่าของคอลัมน์ที่ไม่มีช่องว่างเลยคุณจะต้องจัดการค่าด้วยตัวคุณเองไม่ว่าจะเป็นในชั้นของตรรกะทางธุรกิจหรือในฐานข้อมูลผ่านทางทริกเกอร์ (ระวังปัญหาประสิทธิภาพที่อาจเกิดขึ้นจากทริกเกอร์) แน่นอนว่า คุณทำของคุณเองคุณจะต้องต่อสู้กับปัญหาที่เกิดขึ้นพร้อมกัน / ย้อนกลับ / ล้างข้อมูลหลังจากลบ / อื่น ๆ ที่เครื่องยนต์ DB ทำงานรอบ ๆ โดยให้ช่องว่าง)


คุณสามารถให้ข้อมูลอ้างอิงบางส่วนเกี่ยวกับพฤติกรรมนี้ได้หรือไม่?
คำถามล้น

1
มีการอ้างอิงค่อนข้างน้อยเกี่ยวกับเรื่องนี้บน SO และโดยทั่วไป ค้นหา "IDENTITY gaps", "auto_increment gaps" และอื่น ๆ และคุณควรพบการสนทนามากมาย คุณอาจเพิ่มชื่อ DBMS ของคุณเพื่อให้การค้นหามีความเฉพาะเจาะจงมากขึ้น แต่นี่เป็นแนวคิดทั่วไปที่อาจไม่ทำให้เกิดความแตกต่างอย่างแท้จริงเว้นแต่ว่าคุณกำลังมองหาวิธีการทำงานที่ละเอียด
David Spillett

4
ดูรายละเอียดสำหรับ MySQL: AUTO_INCREMENT การจัดการใน InnoDBที่กล่าวถึง: " ช่องว่างในค่าที่เพิ่มขึ้นโดยอัตโนมัติสำหรับ" การแทรกจำนวนมาก " ... สำหรับโหมดล็อค 1 หรือ 2 ช่องว่างอาจเกิดขึ้นระหว่างคำสั่งต่อเนื่องเพราะสำหรับการแทรกจำนวนมาก ของค่าการเพิ่มอัตโนมัติที่ต้องการโดยแต่ละคำสั่งอาจไม่เป็นที่รู้จักและการประเมินค่าสูงเกินไปเป็นไปได้ "
ypercubeᵀᴹ

@percube ขอบคุณนั่นเป็นประโยชน์กับคุณมากที่สุด
คำถามมากเกินไป

ยังเห็นbugs.mysql.com/bug.php?id=34696
trss
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.