Tại sao số gia tăng tự động nhảy nhiều hơn số lượng hàng được chèn?


11

Tôi rất bối rối vì hành vi kỳ lạ này mà tôi đang thấy trong auto_incrementgiá trị được ghi trong hồ sơ dự thầu của bảng Giá thầu sau khi thực hiện chèn số lượng lớn bằng cách sử dụng quy trình được lưu trữ:

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;

Ví dụ: nếu auto_incrementgiá trị priceID là 101 khi bắt đầu và tôi đã chèn 100 hàng, giá trị kết thúc sẽ là 213 thay vì 201. Tuy nhiên, các giá trị của các hàng được chèn đó chạy liên tục đến tối đa 201.

Có kiểm tra như sau,

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

Tôi không biết tại sao nó lại xảy ra. Điều gì có thể gây ra bước nhảy trong auto incrementgiá trị?


Bảng MyISAM hoặc InnoDB?
Cristian Porta

@CristianPorta, đó là InnoDB.
Câu hỏi tràn vào

Bạn có thể chia sẻ show variables like '%innodb_autoinc_lock_mode%';đầu ra của bạn ?
Cristian Porta

Bạn có chắc chắn không có kết nối / hoạt động nào khác liên quan đến bảng (chèn hàng) không?
ypercubeᵀᴹ

1
@QuestionOverflow điểm khởi đầu tốt: dev.mysql.com/doc/refman/5.5/en/ mẹo
Cristian Porta

Câu trả lời:


10

Điều này không phải là bất thường và có một vài nguyên nhân. Đôi khi, do sự tối ưu hóa mà người chạy truy vấn thực hiện để giảm các vấn đề tranh chấp với tài nguyên truy cập, cải thiện hiệu quả khi có các cập nhật đồng thời cho bảng bị ảnh hưởng. Đôi khi, đó là do các giao dịch được khôi phục rõ ràng (hoặc hoàn toàn quay lại do gặp phải lỗi).

Đảm bảo duy nhất từ ​​một auto_incrementcột (hoặc IDENTITYtrong MSSQL và các tên khác mà khái niệm này sử dụng) là mỗi giá trị sẽ là duy nhất và không bao giờ nhỏ hơn giá trị trước: vì vậy bạn có thể dựa vào các giá trị để đặt hàng nhưng bạn không thể dựa vào họ không có khoảng trống.

Tất nhiên, nếu bạn cần các giá trị của cột không có khoảng trống, bạn sẽ cần phải tự mình quản lý các giá trị, trong một lớp logic nghiệp vụ khác hoặc trong DB thông qua một trình kích hoạt (mặc dù vậy, hãy cẩn thận với các vấn đề về hiệu suất với trình kích hoạt) bạn tự thực hiện, bạn sẽ phải đối mặt với tất cả các vấn đề tương tranh / rollback / dọn dẹp sau khi xóa / các vấn đề khác mà các công cụ DB giải quyết bằng cách cho phép các khoảng trống).


Bạn có thể cung cấp một số tài liệu tham khảo nơi hành vi này đang được thảo luận?
Câu hỏi tràn vào

1
Có khá nhiều tài liệu tham khảo về vấn đề ở đây, trên SO, và nói chung. Tìm kiếm "khoảng trống IDENTITY", "khoảng trống auto_increment", v.v. và bạn sẽ tìm thấy nhiều cuộc thảo luận. Bạn có thể thêm tên DBMS của mình để tìm kiếm cụ thể hơn, mặc dù đây là một khái niệm khá chung chung để có thể không tạo ra bất kỳ sự khác biệt thực sự nào trừ khi bạn đang xem xét chi tiết về cách thức hoạt động của nó.
David Spillett

4
Xem chi tiết về MySQL: AUTO_INCREMENT Xử lý trong InnoDB , trong đó có đề cập: " Khoảng trống trong các giá trị tăng tự động cho chèn số lượng lớn của nhóm Chèn ... Đối với các chế độ khóa 1 hoặc 2, các khoảng trống có thể xảy ra giữa các câu lệnh liên tiếp có thể không biết các giá trị tăng tự động theo yêu cầu của từng câu lệnh và có thể đánh giá quá cao. "
ypercubeᵀᴹ

@ypercube, cảm ơn, đó là hữu ích nhất của bạn.
Câu hỏi tràn vào

Đồng thời xem bug.mysql.com/orms.php?id=34696 .
trss
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.