MySQL 自增ID 和 UUID 做主键的初步性能研究

这几天在纠结数据表主键的设计问题,考虑使用自增ID还是UUID来做主键,数据库后端为MySQL。
首先在互联网上搜索,得到实测 Mysql UUID 性能这篇文章,他的结论是:

当数据表的引擎为MyISAM 时,自增 ID 无疑是效率最高的, UUID 效率略低,但不会低到无法接受。一旦数据引擎为 InnodB 时,效率下降非常严重,已经达到令人发指的地步。由于 InnodB 主键采用 聚集索引 ,会对插入的记录进行物理排序,而 UUID本身基本上是无序的,所以造成了巨大的 I/O 开销。所以如果使用 innodB 千万不要使用 UUID 。

结论经过我后来的测试验证基本正确,但是对这篇文章中间的测试方法不敢苟同。

其测试过程中重大错误:针对自增id的两个表的插入操作没有写入varchar字段,考虑到varchar插入的性能消耗,这一点是绝对不能够忽略的!

建立四张测试用表:

uuidtest_inno(uuid,text),
idtest_inno(id,text),
uuidtest_myisam(uuid,text),
idtest_myisam(id,text)

建立四个存储过程,测试数据量插入100 000行:

DROP PROCEDURE IF EXISTS p_uuid_inno//
CREATE PROCEDURE p_uuid_inno()
BEGIN
DECLARE i INT;
SET i=0;
WHILE i

清空这四个表:

TRUNCATE inttest_inno//
TRUNCATE uuidtest_inno//
TRUNCATE inttest_myisam//
TRUNCATE uuidtest_myisam//

执行存储过程:

call p_int_myisam()//
call p_uuid_myisam()//
call p_int_inno()//
call p_uuid_inno()//

发现执行时间巨长无比。无奈,将测试数据量缩减到1000次插入。
myisam的时间都是0.2s左右,innodb为55s左右。

考虑数据库优化,放弃ACID支持,
设置 innodb_flush_log_at_trx_commit = 2
得到:

mysql> call p_int_myisam();
Query OK, 1 row affected (2.02 sec)

mysql> call p_uuid_myisam();
Query OK, 1 row affected (2.63 sec)

mysql> call p_int_inno();
Query OK, 1 row affected (9.71 sec)

mysql> call p_uuid_inno();
Query OK, 1 row affected (13.88 sec)

再设置 innodb_flush_method = O_DIRECT
得到:

mysql> call p_int_myisam();
Query OK, 1 row affected (2.06 sec)

mysql> call p_uuid_myisam();
Query OK, 1 row affected (2.56 sec)

mysql> call p_int_inno();
Query OK, 1 row affected (7.59 sec)

mysql> call p_uuid_inno();
Query OK, 1 row affected (10.88 sec)

再设置 innodb_log_buffer_size = 8M(之前的设置是3M)
得到:

mysql> call p_int_myisam();
Query OK, 1 row affected (1.96 sec)

mysql> call p_uuid_myisam();
Query OK, 1 row affected (2.63 sec)

mysql> call p_int_inno();
Query OK, 1 row affected (5.28 sec)

mysql> call p_uuid_inno();
Query OK, 1 row affected (9.59 sec)

可以看到对innodb来说插入速度低于myisam,这与选择uuid还是自增ID做主键没有太大的关系,uuid的确要比自增ID慢但是不至于说是数量级上的慢。

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.