Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why INSERT IGNORE increments the auto_increment primary key?

Tags:

mysql

I wrote a java program that accesses a MySQL innodb database.

Whenever an INSERT IGNORE statement encounters a duplicate entry the Auto Increment primary key is incremented.

Is this behaviour the expected? I think it shouldn't happen with IGNORE. That means that IGNORE actually incurs an extra overhead for writing the new primary key value.

The table is the following:

CREATE TABLE `tablename` (   `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,   `rowname` varchar(50) NOT NULL,   PRIMARY KEY (`id`),   UNIQUE KEY `rowname` (`rowname`) ) ENGINE=InnoDB  DEFAULT CHARSET=latin1; 

Thank you!

like image 390
Vasilis Avatar asked Apr 13 '11 20:04

Vasilis


People also ask

Does primary key need auto increment?

Auto-increment allows a unique number to be generated automatically when a new record is inserted into a table. Often this is the primary key field that we would like to be created automatically every time a new record is inserted.

Why does auto increment jumps by more than the number of rows inserted?

It could have multiple causes: Check if the auto_increment value on the table itself, has the next highest value. Mind that if you have transactions where you INSERT a row and rollback the transaction, that auto_increment value will be gone/skipped.

What is insert ignore into?

The INSERT IGNORE command keeps the first set of the duplicated records and discards the remaining. The REPLACE command keeps the last set of duplicates and erases out any earlier ones. Another way to enforce uniqueness is to add a UNIQUE index rather than a PRIMARY KEY to a table.

How do I reset my auto increment primary key?

In MySQL, the syntax to reset the AUTO_INCREMENT column using the ALTER TABLE statement is: ALTER TABLE table_name AUTO_INCREMENT = value; table_name. The name of the table whose AUTO_INCREMENT column you wish to reset.


2 Answers

This has been the default behaviour since MySQL 5.1.22.

You can set the configuration variable innodb_autoinc_lock_mode to 0 (a.k.a “traditional” lock mode) If you'd like to avoid gaps in your auto-increment columns. It may incur a performance penalty, though, as this mode has the effect of holding a table lock until the INSERT completes.

From the docs on InnoDB AUTO_INCREMENT Lock Modes:

innodb_autoinc_lock_mode = 0 (“traditional” lock mode)

The traditional lock mode provides the same behavior that existed before the innodb_autoinc_lock_mode configuration parameter was introduced in MySQL 5.1. The traditional lock mode option is provided for backward compatibility, performance testing, and working around issues with “mixed-mode inserts”, due to possible differences in semantics.

In this lock mode, all “INSERT-like” statements obtain a special table-level AUTO-INC lock for inserts into tables with AUTO_INCREMENT columns. This lock is normally held to the end of the statement (not to the end of the transaction) to ensure that auto-increment values are assigned in a predictable and repeatable order for a given sequence of INSERT statements, and to ensure that auto-increment values assigned by any given statement are consecutive.

like image 98
Eugene Yarmash Avatar answered Sep 21 '22 17:09

Eugene Yarmash


I believe this is a configurable setting in InnoDB. See: AUTO_INCREMENT Handling in InnoDB

You'd want to go with

innodb_autoinc_lock_mode = 0 
like image 33
Joe Stefanelli Avatar answered Sep 19 '22 17:09

Joe Stefanelli