Denne adfærd er dokumenteret (afsnit i parentes):
Hvis du angiver ON DUPLICATE KEY UPDATE, og der indsættes en række, der ville forårsage en dubletværdi i et UNIKT indeks eller PRIMÆR NØGLE, udfører MySQL en OPDATERING af den gamle række. For eksempel, hvis kolonne a er erklæret som UNIQUE og indeholder værdien 1, har følgende to udsagn lignende effekt:
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;
(Effekterne er ikke identiske for InnoDB-tabel, hvor a er en auto-increment-kolonne. Med en auto-increment-kolonne øger en INSERT-sætning værdien for auto-increment, men UPDATE gør det ikke.)
Her er en simpel forklaring. MySQL forsøger at lave indsættelsen først. Dette er, når id'et bliver automatisk forøget. Når den er steget, forbliver den. Så opdages duplikatet, og opdateringen sker. Men værdien bliver savnet.
Du bør ikke være afhængig af auto_increment
uden huller. Hvis det er et krav, er overhead på opdateringer og indsættelser meget større. I bund og grund skal du sætte en lås på hele bordet og omnummerere alt, der skal omnummereres, typisk ved hjælp af en trigger. En bedre løsning er at beregne trinvise værdier på output.