Mengapa kenaikan otomatis melonjak lebih dari jumlah baris yang dimasukkan?

11

Saya sangat terganggu oleh perilaku aneh ini yang saya lihat dalam auto_incrementnilai yang dicatat dalam bidID tabel Tawaran setelah melakukan penyisipan massal menggunakan prosedur tersimpan:

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;

Misalnya, jika nilai auto_incrementbidID adalah 101 saat mulai, dan saya memasukkan 100 baris, nilai akhir menjadi 213 alih-alih 201. Namun, bidID dari baris yang disisipkan itu berjalan secara berurutan hingga maksimum 201.

Setelah memeriksa yang berikut,

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

Saya tidak tahu mengapa itu terjadi. Apa yang bisa menyebabkan lompatan auto incrementnilainya?

Pertanyaan Melimpah
sumber
Tabel MyISAM atau InnoDB?
Cristian Porta
@ ChristianPorta, ini InnoDB.
Pertanyaan Overflow
Bisakah Anda membagikan show variables like '%innodb_autoinc_lock_mode%';hasil Anda ?
Cristian Porta
Apakah Anda yakin tidak ada koneksi / aktivitas lain yang terkait dengan tabel (memasukkan baris)?
ypercubeᵀᴹ
1
@QuestionOverflow titik awal yang baik: dev.mysql.com/doc/refman/5.5/en/…
Cristian Porta

Jawaban:

10

Ini tidak biasa dan ada beberapa penyebab. Kadang-kadang karena optimisasi yang dibuat oleh pelari kueri untuk mengurangi masalah pertentangan dengan sumber daya counter, meningkatkan efisiensi ketika ada pembaruan bersamaan ke tabel yang terpengaruh. Kadang-kadang ini disebabkan oleh transaksi yang secara eksplisit dibatalkan (atau secara implisit dibatalkan karena mengalami kesalahan).

Satu-satunya jaminan dari auto_incrementkolom (atau IDENTITYdalam MSSQL, dan nama-nama lain konsep berjalan) adalah bahwa setiap nilai akan unik dan tidak pernah lebih kecil dari yang sebelumnya: sehingga Anda dapat mengandalkan nilai-nilai untuk pemesanan tetapi Anda tidak dapat mengandalkan mereka tidak memiliki celah.

Jika Anda memerlukan nilai kolom untuk tidak memiliki kesenjangan sama sekali, Anda perlu mengelola sendiri nilai-nilai itu, baik di lapisan logika bisnis lain atau di DB melalui pemicu (hati-hati terhadap masalah kinerja potensial dengan pemicu), tentu saja jika Jika Anda melakukan roll sendiri, Anda harus bersaing dengan semua masalah concurrency / rollback / cleanup-after-delete / lainnya yang ditangani oleh mesin DB dengan membiarkan celah).

David Spillett
sumber
Bisakah Anda memberikan beberapa referensi di mana perilaku ini dibahas?
Question Overflow
1
Ada beberapa referensi untuk masalah ini di sini, di SO, dan secara umum. Cari "celah IDENTITAS", "celah auto_increment", dan sebagainya, dan Anda harus menemukan banyak diskusi. Anda dapat menambahkan nama DBMS Anda untuk membuat pencarian lebih spesifik, meskipun ini adalah konsep yang cukup umum sehingga mungkin tidak membuat perbedaan nyata kecuali Anda mencari di bawah kap di bagaimana ia bekerja secara detail.
David Spillett
4
Lihat detail untuk MySQL: AUTO_INCREMENT Menangani di InnoDB , di mana disebutkan: " Kesenjangan nilai kenaikan otomatis untuk" sisipan massal " ... Untuk mode kunci 1 atau 2, kesenjangan dapat terjadi di antara pernyataan berturut-turut karena untuk massal memasukkan angka yang tepat dari nilai kenaikan otomatis yang diperlukan oleh setiap pernyataan mungkin tidak diketahui dan perkiraan berlebihan mungkin terjadi. "
ypercubeᵀᴹ
@ ypercube, terima kasih, itu yang paling membantu Anda.
Pertanyaan Overflow