Toto chování je zdokumentováno (odstavec v závorce):
Pokud zadáte ON DUPLICATE KEY UPDATE a vloží se řádek, který by způsobil duplicitní hodnotu v UNIQUE indexu nebo PRIMARY KEY, MySQL provede UPDATE starého řádku. Pokud je například sloupec a deklarován jako UNIKÁTNÍ a obsahuje hodnotu 1, následující dva příkazy mají podobný účinek:
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;
(Efekty nejsou totožné pro tabulku InnoDB, kde a je sloupec s automatickým přírůstkem. U sloupce s automatickým přírůstkem příkaz INSERT zvyšuje hodnotu automatického přírůstku, ale UPDATE nikoli.)
Zde je jednoduché vysvětlení. MySQL se pokusí provést vložení jako první. To je, když se ID automaticky zvýší. Jakmile se zvýší, zůstane. Poté je detekován duplikát a dojde k aktualizaci. Ale hodnota se minula.
Neměli byste se spoléhat na auto_increment
nemající žádné mezery. Pokud je to požadavek, režie na aktualizace a vložky je mnohem větší. V podstatě musíte zamknout celý stůl a přečíslovat vše, co je třeba přečíslovat, obvykle pomocí spouště. Lepším řešením je vypočítat přírůstkové hodnoty na výstupu.