372

How do I get the current AUTO_INCREMENT value for a table in MySQL?

nobody
  • 19,814
  • 17
  • 56
  • 77
bparise
  • 3,809
  • 2
  • 13
  • 5
  • 38
    This question is not necessarily a duplicate. The linked question is asking for row count, and the accepted answer ONLY gets row count, NOT AUTO_INCREMENT - which is an entirely different question. – methai Apr 05 '13 at 14:12

9 Answers9

703

You can get all of the table data by using this query:

SHOW TABLE STATUS FROM `DatabaseName` WHERE `name` LIKE 'TableName' ;

You can get exactly this information by using this query:

SELECT `AUTO_INCREMENT`
FROM  INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'DatabaseName'
AND   TABLE_NAME   = 'TableName';
Harshil Sharma
  • 2,016
  • 1
  • 29
  • 54
methai
  • 8,835
  • 1
  • 22
  • 21
  • 48
    Can also use `DATABASE()` instead of explicit database name. – M. Suleiman Apr 04 '13 at 20:58
  • 25
    Note: DATABASE() is NULL if you have not issued a USE *DATABASE* command – methai Apr 05 '13 at 14:13
  • 8
    Is there a reason you can't `SELECT MAX(id) FROM table_name`? – Brian Apr 08 '15 at 23:53
  • 60
    what if you deleted the last record? max won't give you the current auto_increment – peterpeterson May 05 '15 at 14:41
  • 9
    Does this give the latest AUTO_INCREMENT value in the table or what the nnext value is going to be? – sidx Aug 19 '15 at 06:50
  • 3
    I have confirmed that it gives the next, assuming a single-user environment. I don't know how operating in a multi-user environment would affect things, but I am currently trying to find out. – toonice Nov 24 '15 at 07:04
  • 2
    @Brian this approach is much faster, MAX() has to scan all the rows in the table. – John Hunt Mar 08 '16 at 10:46
  • 5
    this give next `auto increment` value not current `auto increment` – slier Sep 01 '16 at 09:15
  • These does not seem to work for MyISAM tables, I get only 1 as result. I do get the expected answer for InnoDB. – Samuel Åslund Dec 08 '16 at 13:05
  • 2
    Both of these queries are very long for a quick lookup by hand. What I was looking for (but couldn't remember the exact keywords) was this: `SHOW TABLE STATUS LIKE 'table_name';` which seems to work fine without the extra `FROM 'DatabaseName' WHERE name ...` portion. – Matt Jul 05 '17 at 21:38
  • What happens if in 2 concurrent transactions, the select is called but no insert was done yet in any transaction? Both selects will give the same auto_increment value? I noticed with myBatis around 30ms of gap from the moment the selectkey is executed and the insert with that id. – Davideas Aug 20 '17 at 20:53
  • @Brian what if the table is empty (but not truncated)? – Anarcociclista Dec 20 '18 at 09:37
  • @Anarcociclista it would be 0 – Brian Dec 21 '18 at 16:09
  • `SHOW TABLE STATUS FROM dbYourDatabaseName WHERE name LIKE 'tblYourTableName';` I couldn't use quotes around database name and name. I had to use what I pasted there. Don't change name. – steviesama Mar 14 '19 at 22:53
  • 1
    @JohnHunt, not trying to defend using `max` but it's actually faster than querying `INFORMATION_SCHEMA`, checked one of my table with ~400million records – Alan Mar 15 '19 at 12:58
  • 3
    I had trouble with this value being cached, so be ware of possible faulty value due to caching. – Halvor Holsten Strand Oct 05 '20 at 11:05
  • i get false value – Riki krismawan Oct 14 '21 at 03:08
  • If you are enquiring about table in current database then simply - `SHOW TABLE STATUS WHERE NAME LIKE ""` – Payel Senapati Nov 30 '21 at 07:39
  • @slier AUTO_INCREMENT is the next value to be inserted in auto increment column by definition. There is no current or next auto_increment – Whip Feb 20 '22 at 08:03
  • 1
    @sidx this does return the next auto increment value, but it is cached (default cache duration is 24h). To get the UP TO DATE auto increment value just run "SET information_schema_stats_expiry = 0;" before the query. – aetonsi May 12 '22 at 07:55
34

If you just want to know the number, rather than get it in a query then you can use:

SHOW CREATE TABLE tablename;

You should see the auto_increment at the bottom

johnnyjohnny
  • 341
  • 3
  • 4
22

I believe you're looking for MySQL's LAST_INSERT_ID() function. If in the command line, simply run the following:

LAST_INSERT_ID();

You could also obtain this value through a SELECT query:

SELECT LAST_INSERT_ID();
jvdub
  • 891
  • 5
  • 19
  • 5
    It's not the best idea to add one to it and expect, it will be the ID of next row. In the mean time another transaction could insert a new row and you would use the wrong ID right? – agim Apr 04 '13 at 21:11
  • You're right. I guess it depends on the environment you're running in. If it's a controlled test environment, then you could most likely add one and be safe. The best answer was provided by methai. – jvdub Apr 04 '13 at 21:18
  • 2
    What the best answer is, depends on what you want to achieve. If you insert a new row and you want to know the created ID, then your answer is the best answer, since LAST_INSERT_ID() is transaction safe and ensures, you get the ID for the created object. I voted your answer up but I would delete the part with 'add one to it...' – agim Apr 04 '13 at 22:24
  • 40
    LAST_INSERT_ID() is per connection. That means, if another process inserts three additional rows after you, YOUR LAST_INSERT_ID() call will be different than theirs. This question is asking for the current AUTO_INC val on the table itself. – methai Apr 05 '13 at 14:08
  • 2
    If the last INSERT statement inserted more than one row, this will give you the wrong answer. MySQL documentation (emphasis added): "LAST_INSERT_ID() returns a 64-bit value representing the *first* automatically generated value successfully inserted for an AUTO_INCREMENT column as a result of the most recently executed INSERT statement." Intuitive! http://dev.mysql.com/doc/refman/5.6/en/information-functions.html#function_last-insert-id – Charlie Jun 12 '15 at 22:04
  • This answer seems to be much better when 2 concurrent inserts are executed with no commit done yet. I will add a new answer to explain better... – Davideas Aug 20 '17 at 21:07
  • SELECT LAST_INSERT_ID((); retuns ZERO unles it is immediately preceded by an INSERT statement. I know that this is so because I tried it out a couple of hours ago. However, all is not lost, since the answer marked as accepted gets the job done. – David A. Gray Feb 11 '19 at 21:23
10

Even though methai's answer is correct if you manually run the query, a problem occurs when 2 concurrent transaction/connections actually execute this query at runtime in production (for instance).

Just tried manually in MySQL workbench with 2 connections opened simultaneously:

CREATE TABLE translation (
  id BIGINT PRIMARY KEY AUTO_INCREMENT
);
# Suppose we have already 20 entries, we execute 2 new inserts:

Transaction 1:

21 = SELECT `AUTO_INCREMENT` FROM INFORMATION_SCHEMA.TABLES
     WHERE TABLE_SCHEMA = 'DatabaseName' AND TABLE_NAME = 'translation';

insert into translation (id) values (21);

Transaction 2:

21 = SELECT `AUTO_INCREMENT` FROM INFORMATION_SCHEMA.TABLES
     WHERE TABLE_SCHEMA = 'DatabaseName' AND TABLE_NAME = 'translation';

insert into translation (id) values (21);

# commit transaction 1;
# commit transaction 2;
  • Insert of transaction 1 is ok
  • Insert of transaction 2 goes in error: Error Code: 1062. Duplicate entry '21' for key 'PRIMARY'.

A good solution would be jvdub's answer because per transaction/connection the 2 inserts will be:

Transaction 1:

insert into translation (id) values (null);
21 = SELECT LAST_INSERT_ID();

Transaction 2:

insert into translation (id) values (null);
22 = SELECT LAST_INSERT_ID();

# commit transaction 1;
# commit transaction 2;

But we have to execute the last_insert_id() just after the insert! And we can reuse that id to be inserted in others tables where a foreign key is expected!

Also, we cannot execute the 2 queries as following:

insert into translation (id) values ((SELECT AUTO_INCREMENT FROM
    information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE()
    AND TABLE_NAME='translation'));

because we actually are interested to grab/reuse that ID in other table or to return!

EDIT: 02/08/2021, Retrieving the value

To actually retrieve the value in the application (example done in Java with MyBatis):

@Mapper
public interface ClientMapper {
    @Select("select last_insert_id()")
    Long getLastInsertedId();

    @Insert({...})
    void insertClientInfo(ClientInfo client);
}

And then in Repository

public void insertClientInfo(ClientInfo clientInfo) {
    mapper.insertClientInfo(clientInfo);
    Long pk = mapper.getLastInsertedId();
    clientInfo.setId(pk);
}
Davideas
  • 3,226
  • 2
  • 33
  • 51
  • 2
    Good explanation! thanks. It's now clear why would we want to use `last_insert_id()` – Imtiaz Sep 19 '17 at 22:20
  • 3
    This is an interesting scenario, but I don't think it actually answers the question which is to retrieve the `AUTO_INCREMENT` value. – Sharlike Nov 21 '18 at 21:38
  • @Sharlike, I added the usage. – Davideas Aug 02 '21 at 11:58
  • Thanks @Davideas, now i'm understand that LAST_INSERT_ID for transaction more secure, And that Table Scheme use only when we need other table next increment number. – Taurus Silver Sep 01 '22 at 16:28
5

mysqli executable sample code:

<?php
    $db = new mysqli("localhost", "user", "password", "YourDatabaseName");
    if ($db->connect_errno) die ($db->connect_error);

    $table=$db->prepare("SHOW TABLE STATUS FROM YourDatabaseName");
    $table->execute();
    $sonuc = $table->get_result();
    while ($satir=$sonuc->fetch_assoc()){
        if ($satir["Name"]== "YourTableName"){
            $ai[$satir["Name"]]=$satir["Auto_increment"];
        }
    }
    $LastAutoIncrement=$ai["YourTableName"];
    echo $LastAutoIncrement;
?>  
Joakim Johansson
  • 3,196
  • 1
  • 27
  • 43
Murat Başar
  • 69
  • 1
  • 2
  • you can avoid the while Loop : $table=$db->prepare("SHOW TABLE STATUS FROM YourDatabaseName where Name = 'YourTableName' ") ; $values= $table->get_result(); return $values["Auto_increment"] ; – Jörg velletti Dec 15 '21 at 11:23
5

Query to check percentage "usage" of AUTO_INCREMENT for all tables of one given schema (except columns with type bigint unsigned):

SELECT 
  c.TABLE_NAME,
  c.COLUMN_TYPE,
  c.MAX_VALUE,
  t.AUTO_INCREMENT,
  IF (c.MAX_VALUE > 0, ROUND(100 * t.AUTO_INCREMENT / c.MAX_VALUE, 2), -1) AS "Usage (%)" 
FROM 
  (SELECT 
     TABLE_SCHEMA,
     TABLE_NAME,
     COLUMN_TYPE,
     CASE 
        WHEN COLUMN_TYPE LIKE 'tinyint(1)' THEN 127
        WHEN COLUMN_TYPE LIKE 'tinyint(1) unsigned' THEN 255
        WHEN COLUMN_TYPE LIKE 'smallint(%)' THEN 32767
        WHEN COLUMN_TYPE LIKE 'smallint(%) unsigned' THEN 65535
        WHEN COLUMN_TYPE LIKE 'mediumint(%)' THEN 8388607
        WHEN COLUMN_TYPE LIKE 'mediumint(%) unsigned' THEN 16777215
        WHEN COLUMN_TYPE LIKE 'int(%)' THEN 2147483647
        WHEN COLUMN_TYPE LIKE 'int(%) unsigned' THEN 4294967295
        WHEN COLUMN_TYPE LIKE 'bigint(%)' THEN 9223372036854775807
        WHEN COLUMN_TYPE LIKE 'bigint(%) unsigned' THEN 0
        ELSE 0
     END AS "MAX_VALUE" 
   FROM 
     INFORMATION_SCHEMA.COLUMNS
     WHERE EXTRA LIKE '%auto_increment%'
   ) c

   JOIN INFORMATION_SCHEMA.TABLES t ON (t.TABLE_SCHEMA = c.TABLE_SCHEMA AND t.TABLE_NAME = c.TABLE_NAME)

WHERE
 c.TABLE_SCHEMA = 'YOUR_SCHEMA' 
ORDER BY
 `Usage (%)` DESC;
Jiří Chmiel
  • 876
  • 6
  • 20
  • An excellent option, I would also take into account the moment when the specified length may be missing in `WHEN COLUMN_TYPE LIKE` conditions, and the brackets are superfluous in these queries. – wnull Mar 01 '23 at 20:08
2

I was looking for the same and ended up by creating a static method inside a Helper class (in my case I named it App\Helpers\Database).

The method

/**
 * Method to get the autoincrement value from a database table
 *
 * @access public
 *
 * @param string $database The database name or configuration in the .env file
 * @param string $table    The table name
 *
 * @return mixed
 */
public static function getAutoIncrementValue($database, $table)
{
    $database ?? env('DB_DATABASE');

    return \DB::select("
        SELECT AUTO_INCREMENT 
        FROM information_schema.TABLES 
        WHERE TABLE_SCHEMA = '" . env('DB_DATABASE') . "' 
        AND TABLE_NAME = '" . $table . "'"
    )[0]->AUTO_INCREMENT;
}

To call the method and get the MySql AUTO_INCREMENT just use the following:

$auto_increment = \App\Helpers\Database::getAutoIncrementValue(env('DB_DATABASE'), 'your_table_name');

Hope it helps.

McRui
  • 1,879
  • 3
  • 20
  • 31
2

list dbname all tabename and AUTO_INCREMENT

SELECT `AUTO_INCREMENT`,`TABLE_NAME`
FROM  INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'dbname' ORDER BY AUTO_INCREMENT desc
seqwait
  • 159
  • 1
  • 7
1

If column is autoincremented in sql server then to see the current autoincremented value, and if you want to edit that value for that column use the following query.

-- to get current value
select ident_current('Table_Name')

-- to update current value
dbcc checkident ('[Table_Name]',reseed,"Your Value")
Joakim Johansson
  • 3,196
  • 1
  • 27
  • 43
Mukul
  • 47
  • 3