Databases 9 min read

Why MySQL Discourages UUIDs and Non‑Sequential IDs: Performance Comparison with Auto‑Increment Primary Keys

This article analyzes MySQL's recommendation against UUIDs and non‑sequential keys by benchmarking three tables—auto‑increment, UUID, and random snowflake IDs—using a Spring Boot JdbcTemplate test, revealing that sequential primary keys provide superior insert performance and lower index fragmentation.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Why MySQL Discourages UUIDs and Non‑Sequential IDs: Performance Comparison with Auto‑Increment Primary Keys

MySQL officially recommends using auto_increment sequential primary keys instead of UUIDs or non‑sequential snowflake IDs because of performance concerns.

The article creates three tables (user_auto_key, user_uuid, user_random_key) that differ only in the primary key generation strategy and uses a Spring Boot application with JdbcTemplate to insert and query large amounts of data, measuring insert time.

package com.wyq.mysqldemo;
import cn.hutool.core.collection.CollectionUtil;
import com.wyq.mysqldemo.databaseobject.UserKeyAuto;
import com.wyq.mysqldemo.databaseobject.UserKeyRandom;
import com.wyq.mysqldemo.databaseobject.UserKeyUUID;
import com.wyq.mysqldemo.diffkeytest.AutoKeyTableService;
import com.wyq.mysqldemo.diffkeytest.RandomKeyTableService;
import com.wyq.mysqldemo.diffkeytest.UUIDKeyTableService;
import com.wyq.mysqldemo.util.JdbcTemplateService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.StopWatch;
import java.util.List;

@SpringBootTest
class MysqlDemoApplicationTests {

    @Autowired
    private JdbcTemplateService jdbcTemplateService;

    @Autowired
    private AutoKeyTableService autoKeyTableService;

    @Autowired
    private UUIDKeyTableService uuidKeyTableService;

    @Autowired
    private RandomKeyTableService randomKeyTableService;

    @Test
    void testDBTime() {
        StopWatch stopwatch = new StopWatch("执行sql时间消耗");

        // auto_increment key task
        final String insertSql = "INSERT INTO user_key_auto(user_id,user_name,sex,address,city,email,state) VALUES(?,?,?,?,?,?,?)";
        List
insertData = autoKeyTableService.getInsertData();
        stopwatch.start("自动生成key表任务开始");
        long start1 = System.currentTimeMillis();
        if (CollectionUtil.isNotEmpty(insertData)) {
            boolean insertResult = jdbcTemplateService.insert(insertSql, insertData, false);
            System.out.println(insertResult);
        }
        long end1 = System.currentTimeMillis();
        System.out.println("auto key消耗的时间:" + (end1 - start1));
        stopwatch.stop();

        // UUID key task
        final String insertSql2 = "INSERT INTO user_uuid(id,user_id,user_name,sex,address,city,email,state) VALUES(?,?,?,?,?,?,?,?)";
        List
insertData2 = uuidKeyTableService.getInsertData();
        stopwatch.start("UUID的key表任务开始");
        long begin = System.currentTimeMillis();
        if (CollectionUtil.isNotEmpty(insertData)) {
            boolean insertResult = jdbcTemplateService.insert(insertSql2, insertData2, true);
            System.out.println(insertResult);
        }
        long over = System.currentTimeMillis();
        System.out.println("UUID key消耗的时间:" + (over - begin));
        stopwatch.stop();

        // Random long key task
        final String insertSql3 = "INSERT INTO user_random_key(id,user_id,user_name,sex,address,city,email,state) VALUES(?,?,?,?,?,?,?,?)";
        List
insertData3 = randomKeyTableService.getInsertData();
        stopwatch.start("随机的long值key表任务开始");
        Long start = System.currentTimeMillis();
        if (CollectionUtil.isNotEmpty(insertData)) {
            boolean insertResult = jdbcTemplateService.insert(insertSql3, insertData3, true);
            System.out.println(insertResult);
        }
        Long end = System.currentTimeMillis();
        System.out.println("随机key任务消耗时间:" + (end - start));
        stopwatch.stop();

        String result = stopwatch.prettyPrint();
        System.out.println(result);
    }
}

Test results show that with 1.3 million existing rows, inserting 100 k new rows the auto_increment key is fastest, the random long key is slower, and UUID is the slowest; the performance gap widens as data volume grows.

The article explains the internal index structures: auto_increment keys are sequential, allowing InnoDB to append rows to the end of pages, minimizing page splits and random I/O, while UUIDs are random, causing page splits, fragmentation, and extra disk reads.

It also discusses drawbacks of auto_increment keys, such as exposing business growth information, lock contention under high concurrency, and the overhead of the auto_increment lock mechanism.

Conclusion: for InnoDB tables, using sequential primary keys yields better insert performance and lower fragmentation, though the choice should consider security and concurrency requirements.

PerformanceMySQLauto-incrementUUIDIndexprimary key
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.