Perilaku ini didokumentasikan (paragraf dalam tanda kurung):
Jika Anda menentukan ON DUPLICATE KEY UPDATE, dan sebuah baris disisipkan yang akan menyebabkan nilai duplikat dalam indeks UNIK atau PRIMARY KEY, MySQL melakukan UPDATE dari baris yang lama. Misalnya, jika kolom a dideklarasikan sebagai UNIK dan berisi nilai 1, dua pernyataan berikut memiliki efek yang sama:
INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1; UPDATE table SET c=c+1 WHERE a=1;
(Efeknya tidak identik untuk tabel InnoDB di mana a adalah kolom kenaikan otomatis. Dengan kolom kenaikan otomatis, pernyataan INSERT meningkatkan nilai kenaikan otomatis tetapi UPDATE tidak.)
Berikut ini penjelasan sederhananya. MySQL mencoba melakukan penyisipan terlebih dahulu. Ini adalah saat id bertambah secara otomatis. Setelah bertambah, itu tetap. Kemudian duplikat terdeteksi dan pembaruan terjadi. Tapi nilainya terlewatkan.
Anda tidak boleh bergantung pada auto_increment
tidak memiliki celah. Jika itu adalah persyaratan, overhead pada pembaruan dan sisipan jauh lebih besar. Pada dasarnya, Anda perlu mengunci seluruh tabel, dan memberi nomor ulang semua yang perlu diberi nomor ulang, biasanya menggunakan pemicu. Solusi yang lebih baik adalah menghitung nilai tambahan pada output.