技术

数据库主键设计

2018-12-18  本文已影响48人  良人与我

先来一个测,看看主键长度对查询和插入性能的影响。
两个表
t_book 主键是string 长度 36 字节
t_student 主键是bigint 8字节

CREATE TABLE `t_book` (
  `book_id` varchar(36) NOT NULL,
  `book_desc` varchar(255) DEFAULT NULL,
  `book_name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`book_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `t_student` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `create_time` datetime DEFAULT NULL,
  `sname` varchar(255) DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8mb4;

通过程序每个表插入 100w 条数据
t_book 花费的时间是 t_student 的十倍以上
(已经有100W 再通过程序每次插入1,连续100次。 t_book 花费 35分钟,t_student 花费4分钟)

再看看 查询 count(*) 的性能

SELECT count() from t_book
query time 3.187s
SELECT count(
) from t_student
query time 0.274s

差距在10倍以上

数据是200W时候

SELECT count() from t_book
query time 7.056s
SELECT count(
) from t_student
query time 0.556s

差距依然在10倍以上

插入速度慢原因

因为插入时候主键的生成策略用的是 uuid
因为是无序的,所以每次索引生成时候需要重排序,浪费时间。

查询速度慢原因

查询connt(*)时候,需要将索引读入到内存中。
如果索引长度越长,同样多的索引需要存储的磁盘空间越大。磁盘IO 也是系统中最大的瓶颈。导致整个性能下降。

所以考虑到性能,主键最好是 递增的并且占用存储空间小。

单表情况

可以是 long 型, 自增主键。

分表情况

需要一个id 生成器。
timestemp + 序列号 + 机器号 组成的 数字
需要保证时间不能回滚,否则会出现重复的id

上一篇 下一篇

猜你喜欢

热点阅读