MySQL 使用自增ID主键和UUID 作为主键的优劣比较详细过程(500W单表)

news/2024/7/4 7:47:31
               

 

 

测试缘由

 

 一个开发同事做了一个框架,里面主键是uuid,我跟他建议说mysql不要用uuid用自增主键,自增主键效率高,他说不一定高,我说innodb的索引特性导致了自增id做主键是效率最好的,为了说服他,所以准备做一个详细的测试。

 

 作为互联网公司,一定有用户表,而且用户表UC_USER基本会有百万记录,所以在这个表基础上准测试数据来进行测试。

 

  大概环境是:Centos6.5、MySQL5.6.12

 

 

1、准备表以及数据

UC_USER,自增ID为主键:

CREATE TABLE `UC_USER` (
    `ID` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
    `USER_NAME` varchar(100) DEFAULT NULL COMMENT '用户名',
    `USER_PWD` varchar(200) DEFAULT NULL COMMENT '密码',
    `BIRTHDAY` datetime DEFAULT NULL COMMENT '生日',
    `NAME` varchar(200) DEFAULT NULL COMMENT '姓名',
    `USER_ICON` varchar(500) DEFAULT NULL COMMENT '头像图片',
    `SEX` char(1) DEFAULT NULL COMMENT '性别, 1:男,2:女,3:保密',
    `NICKNAME` varchar(200) DEFAULT NULL COMMENT '昵称',
    `STAT` varchar(10) DEFAULT NULL COMMENT '用户状态,01:正常,02:冻结',
    `USER_MALL` bigint(20) DEFAULT NULL COMMENT '当前所属MALL',
    `LAST_LOGIN_DATE` datetime DEFAULT NULL COMMENT '最后登录时间',
    `LAST_LOGIN_IP` varchar(100) DEFAULT NULL COMMENT '最后登录IP',
    `SRC_OPEN_USER_ID` bigint(20) DEFAULT NULL COMMENT '来源的联合登录',
    `EMAIL` varchar(200) DEFAULT NULL COMMENT '邮箱',
    `MOBILE` varchar(50) DEFAULT NULL COMMENT '手机',
    `IS_DEL` char(1) DEFAULT '0' COMMENT '是否删除',
    `IS_EMAIL_CONFIRMED` char(1) DEFAULT '0' COMMENT '是否绑定邮箱',
    `IS_PHONE_CONFIRMED` char(1) DEFAULT '0' COMMENT '是否绑定手机',
    `CREATER` bigint(20) DEFAULT NULL COMMENT '创建人',
    `CREATE_DATE` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '注册时间',
    `UPDATE_DATE` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '修改日期',
    `PWD_INTENSITY` char(1) DEFAULT NULL COMMENT '密码强度',
    `MOBILE_TGC` char(64) DEFAULT NULL COMMENT '手机登录标识',
    `MAC` char(64) DEFAULT NULL COMMENT 'mac地址',
    `SOURCE` char(1) DEFAULT '0' COMMENT '1:WEB,2:IOS,3:ANDROID,4:WIFI,5:管理系统, 0:未知',
    `ACTIVATE` char(1) DEFAULT '1' COMMENT '激活,1:激活,0:未激活',
    `ACTIVATE_TYPE` char(1) DEFAULT '0' COMMENT '激活类型,0:自动,1:手动',
    PRIMARY KEY (`ID`),
    UNIQUE KEY `USER_NAME` (`USER_NAME`),
    KEY `MOBILE` (`MOBILE`),
    KEY `IDX_MOBILE_TGC` (`MOBILE_TGC`,`ID`),
    KEY `IDX_EMAIL` (`EMAIL`,`ID`),
    KEY `IDX_CREATE_DATE` (`CREATE_DATE`,`ID`),
    KEY `IDX_UPDATE_DATE` (`UPDATE_DATE`)
  ) ENGINE=InnoDB AUTO_INCREMENT=7122681 DEFAULT CHARSET=utf8 COMMENT='用户表'

 

 

 

UC_USER_PK_VARCHAR表,字符串ID为主键,采用uuid

CREATE TABLE `UC_USER_PK_VARCHAR_1` (
  `ID` varchar(36) CHARACTER SET utf8mb4 NOT NULL DEFAULT '0' COMMENT '主键',
    `USER_NAME` varchar(100) DEFAULT NULL COMMENT '用户名',
    `USER_PWD` varchar(200) DEFAULT NULL COMMENT '密码',
    `BIRTHDAY` datetime DEFAULT NULL COMMENT '生日',
    `NAME` varchar(200) DEFAULT NULL COMMENT '姓名',
    `USER_ICON` varchar(500) DEFAULT NULL COMMENT '头像图片',
    `SEX` char(1) DEFAULT NULL COMMENT '性别, 1:男,2:女,3:保密',
    `NICKNAME` varchar(200) DEFAULT NULL COMMENT '昵称',
    `STAT` varchar(10) DEFAULT NULL COMMENT '用户状态,01:正常,02:冻结',
    `USER_MALL` bigint(20) DEFAULT NULL COMMENT '当前所属MALL',
    `LAST_LOGIN_DATE` datetime DEFAULT NULL COMMENT '最后登录时间',
    `LAST_LOGIN_IP` varchar(100) DEFAULT NULL COMMENT '最后登录IP',
    `SRC_OPEN_USER_ID` bigint(20) DEFAULT NULL COMMENT '来源的联合登录',
    `EMAIL` varchar(200) DEFAULT NULL COMMENT '邮箱',
    `MOBILE` varchar(50) DEFAULT NULL COMMENT '手机',
    `IS_DEL` char(1) DEFAULT '0' COMMENT '是否删除',
    `IS_EMAIL_CONFIRMED` char(1) DEFAULT '0' COMMENT '是否绑定邮箱',
    `IS_PHONE_CONFIRMED` char(1) DEFAULT '0' COMMENT '是否绑定手机',
    `CREATER` bigint(20) DEFAULT NULL COMMENT '创建人',
    `CREATE_DATE` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '注册时间',
    `UPDATE_DATE` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '修改日期',
    `PWD_INTENSITY` char(1) DEFAULT NULL COMMENT '密码强度',
    `MOBILE_TGC` char(64) DEFAULT NULL COMMENT '手机登录标识',
    `MAC` char(64) DEFAULT NULL COMMENT 'mac地址',
    `SOURCE` char(1) DEFAULT '0' COMMENT '1:WEB,2:IOS,3:ANDROID,4:WIFI,5:管理系统, 0:未知',
    `ACTIVATE` char(1) DEFAULT '1' COMMENT '激活,1:激活,0:未激活',
    `ACTIVATE_TYPE` char(1) DEFAULT '0' COMMENT '激活类型,0:自动,1:手动',
    PRIMARY KEY (`ID`),
    UNIQUE KEY `USER_NAME` (`USER_NAME`),
    KEY `MOBILE` (`MOBILE`),
    KEY `IDX_MOBILE_TGC` (`MOBILE_TGC`,`ID`),
    KEY `IDX_EMAIL` (`EMAIL`,`ID`),
    KEY `IDX_CREATE_DATE` (`CREATE_DATE`,`ID`),
    KEY `IDX_UPDATE_DATE` (`UPDATE_DATE`)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表';

 

 

 

 

2、500W数据测试

2.1 录入500W数据,自增ID节省一半磁盘空间

确定两个表数据量

# 自增id为主键的表

 

mysql> select count(1) from UC_USER;

 

+----------+

 

| count(1) |

 

+----------+

 

|   5720112 |

 

+----------+

 

1 row in set (0.00 sec)

 

 

 

mysql>

 

 

 

# uuid为主键的表

 

mysql> select count(1) from  UC_USER_PK_VARCHAR_1;                     

 

+----------+

 

| count(1) |

 

+----------+

 

|   5720112 |

 

+----------+

 

1 row in set (1.91 sec)

 

占据的空间容量来看,自增ID比UUID小一半左右。

           

主键类型

数据文件大小

占据容量

自增ID

-rw-rw---- 1 mysql mysql 2.5G Aug 11  18:29 UC_USER.ibd

2.5 G

UUID

-rw-rw---- 1 mysql mysql 5.4G Aug 15  15:11 UC_USER_PK_VARCHAR_1.ibd

5.4 G

 

 

 

2.2 单个数据走索引查询,自增id和uuid相差不大

                                       

主键类型

SQL语句

执行时间 (秒)

自增ID

SELECT SQL_NO_CACHE t.* FROM  test.`UC_USER` t WHERE t.`MOBILE` ='14782121512';

0.118

 

 

 

UUID

SELECT SQL_NO_CACHE t.* FROM  test.`UC_USER_PK_VARCHAR_1` t WHERE t.`MOBILE` ='14782121512';

0.117

 

 

 

自增ID

SELECT SQL_NO_CACHE t.* FROM  test.`UC_USER` t WHERE t.`MOBILE` IN( '14782121512','13761460105');

0.049

UUID

SELECT SQL_NO_CACHE t.* FROM  test.`UC_USER_PK_VARCHAR_1` t WHERE t.`MOBILE`  IN('14782121512','13761460105');

0.040

 

 

 

自增ID

SELECT SQL_NO_CACHE t.* FROM  test.`UC_USER` t WHERE t.`CREATE_DATE`='2013-11-24 10:26:36' ;

0.139

UUID

SELECT SQL_NO_CACHE t.* FROM  test.`UC_USER_PK_VARCHAR_1` t WHERE t.`CREATE_DATE`='2013-11-24 10:26:43' ;

0.126

 

 

 

2.3 范围like查询,自增ID性能优于UUID

                                   

主键类型

SQL语句

执行时间 (秒)

 

 

(1)模糊范围查询1000条数据,自增ID性能要好于UUID

自增ID

SELECT SQL_NO_CACHE t.* FROM  test.`UC_USER` t WHERE t.`MOBILE` LIKE '147%' LIMIT 1000;

1.784

UUID

SELECT  SQL_NO_CACHE t.* FROM test.`UC_USER_PK_VARCHAR_1` t WHERE t.`MOBILE` LIKE  '147%' LIMIT 1000;

3.196

 

 

(2)日期范围查询20条数据,自增ID稍微弱于UUID

自增ID

SELECT SQL_NO_CACHE t.* FROM  test.`UC_USER` t WHERE t.`CREATE_DATE` > '2016-08-01 10:26:36' ORDER BY  t.`UPDATE_DATE` DESC LIMIT 20;

0.601

UUID

SELECT SQL_NO_CACHE t.* FROM  test.`UC_USER_PK_VARCHAR_1` t WHERE t.`CREATE_DATE` > '2016-08-01  10:26:36' ORDER BY t.`UPDATE_DATE` DESC LIMIT 20;

0.543

 

 

(3)范围查询200条数据,自增ID性能要好于UUID

自增ID

SELECT SQL_NO_CACHE t.* FROM test.`UC_USER`  t WHERE t.`CREATE_DATE` > '2016-07-01 10:26:36' ORDER BY t.`UPDATE_DATE`  DESC LIMIT 200;

2.314

UUID

SELECT  SQL_NO_CACHE t.* FROM test.`UC_USER_PK_VARCHAR_1` t WHERE t.`CREATE_DATE`  > '2016-07-01 10:26:36' ORDER BY t.`UPDATE_DATE` DESC LIMIT 200;

3.229

 

 

范围查询总数量,自增ID要好于UUID

自增ID

SELECT SQL_NO_CACHE COUNT(1) FROM  test.`UC_USER` t WHERE t.`CREATE_DATE` > '2016-07-01 10:26:36'  ;

0.514

UUID

SELECT  SQL_NO_CACHE COUNT(1) FROM test.`UC_USER_PK_VARCHAR_1` t WHERE  t.`CREATE_DATE` > '2016-07-01 10:26:36'   ;

1.092

 

 

 

PS:在有缓存的情况下,两者执行效率没有相差很小。

 

 

 

2.4 写入测试,自增ID是UUID的4倍

                           

主键类型

SQL语句

执行时间 (秒)

 

 

 

 

 

 

 

自增ID

UPDATE test.`UC_USER` t SET  t.`MOBILE_TGC`='T2' WHERE t.`CREATE_DATE` > '2016-05-03 10:26:36' AND  t.`CREATE_DATE` <'2016-05-04 00:00:00'   ;

1.419  

UUID

UPDATE test.`UC_USER_PK_VARCHAR_1` t SET  t.`MOBILE_TGC`='T2' WHERE t.`CREATE_DATE` > '2016-05-03 10:26:36' AND  t.`CREATE_DATE` <'2016-05-04 00:00:00'   ;

5.639

 

 

 

自增ID

INSERT INTO test.`UC_USER`(   ID,    `USER_NAME`,   `USER_PWD`,   `BIRTHDAY`,   `NAME`,    `USER_ICON`,   `SEX`,   `NICKNAME`,   `STAT`,    `USER_MALL`,    `LAST_LOGIN_DATE`,    `LAST_LOGIN_IP`,    `SRC_OPEN_USER_ID`,   `EMAIL`,   `MOBILE`,    `IS_DEL`,    `IS_EMAIL_CONFIRMED`,    `IS_PHONE_CONFIRMED`,    `CREATER`,   `CREATE_DATE`,   `UPDATE_DATE`,   `PWD_INTENSITY`,   `MOBILE_TGC`,   `MAC`,    `SOURCE`,   `ACTIVATE`,   `ACTIVATE_TYPE` ) SELECT       NULL,    CONCAT('110',`USER_NAME`,8),   `USER_PWD`,   `BIRTHDAY`,   `NAME`,    `USER_ICON`,   `SEX`,   `NICKNAME`,   `STAT`,    `USER_MALL`,   `LAST_LOGIN_DATE`,   `LAST_LOGIN_IP`,   `SRC_OPEN_USER_ID`,   `EMAIL`,  CONCAT('110',TRIM(`MOBILE`)),    `IS_DEL`,    `IS_EMAIL_CONFIRMED`,    `IS_PHONE_CONFIRMED`,    `CREATER`,   `CREATE_DATE`,   `UPDATE_DATE`,   `PWD_INTENSITY`,   `MOBILE_TGC`,   `MAC`,    `SOURCE`,   `ACTIVATE`,   `ACTIVATE_TYPE` FROM `test`.`UC_USER_1`  LIMIT 100;

0.105

UUID

INSERT INTO  test.`UC_USER_PK_VARCHAR_1`(     ID,   `USER_NAME`,   `USER_PWD`,   `BIRTHDAY`,   `NAME`,    `USER_ICON`,   `SEX`,   `NICKNAME`,   `STAT`,    `USER_MALL`,    `LAST_LOGIN_DATE`,   `LAST_LOGIN_IP`,   `SRC_OPEN_USER_ID`,   `EMAIL`,    `MOBILE`,   `IS_DEL`,   `IS_EMAIL_CONFIRMED`,   `IS_PHONE_CONFIRMED`,   `CREATER`,   `CREATE_DATE`,   `UPDATE_DATE`,   `PWD_INTENSITY`,   `MOBILE_TGC`,   `MAC`,    `SOURCE`,   `ACTIVATE`,   `ACTIVATE_TYPE` ) SELECT         UUID(),   CONCAT('110',`USER_NAME`,8),   `USER_PWD`,   `BIRTHDAY`,   `NAME`,    `USER_ICON`,   `SEX`,   `NICKNAME`,   `STAT`,    `USER_MALL`,    `LAST_LOGIN_DATE`,    `LAST_LOGIN_IP`,    `SRC_OPEN_USER_ID`,   `EMAIL`,  CONCAT('110',TRIM(`MOBILE`)),    `IS_DEL`,    `IS_EMAIL_CONFIRMED`,    `IS_PHONE_CONFIRMED`,    `CREATER`,   `CREATE_DATE`,   `UPDATE_DATE`,   `PWD_INTENSITY`,   `MOBILE_TGC`,   `MAC`,    `SOURCE`,   `ACTIVATE`,   `ACTIVATE_TYPE` FROM `test`.`UC_USER_1`  LIMIT 100;

0.424

 

 

 

 

3、总结

在500W记录表的测试下:

(1)      普通单条或者20条左右的记录检索,uuid为主键的相差不大几乎效率相同;

(2)      但是范围查询特别是上百成千条的记录查询,自增id的效率要大于uuid;

(3)      在范围查询做统计汇总的时候,自增id的效率要大于uuid;

(4)      在存储上面,自增id所占的存储空间是uuid的1/2;

 

           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow


http://www.niftyadmin.cn/n/3653839.html

相关文章

从google搜索量走势分析IDE未来走向

下图是笔者最近通过google网上的google trends功能搜索netbeans&#xff0c;eclipse&#xff0c;JBuilder以及交叉搜索得到的一些图表&#xff1a;图一 (netbean搜索量和新闻引用量趋势率)图二  (eclipse搜索量和新闻引用量趋势率)图三  (jbuilder搜索量和新闻引用量趋势率)…

ORACLE11g ORA-12514 TNS 监听程序当前无法识别连接描述符中请求的服务

1、TNS连接错误同事跟我说连接oracle数据库报错ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务&#xff0c;如下所示&#xff1a;2、查看本地TNSPING查看本地的tns配置&#xff1a;WXX (DESCRIPTION (ADDRESS (PROTOCOL TCP)(HOST 192.168.121.58…

(编辑整理) NetBeans vs Eclipse 之性能参数对比

这两款JAVA IDE都是一流的开源软件&#xff0c;那么对于广大的JAVA学习者及开发人员来说&#xff0c;那款更适合自己呢&#xff1f;本文通过图文对这两款软件进行多方面的分析比较&#xff0c;仅供参考之用&#xff0c;以期让广大的JAVA学习者少走弯路而已。1. 简介NetBeans:在…

Sqlite -- Java使用jdbc连接Sqlite数据库进行各种数据操作的详细过程

引&#xff1a;1&#xff0c; Sqlite在Windows、Linux 和 Mac OS X 上的安装过程2&#xff0c;嵌入式数据库的安装、建库、建表、更新表结构以及数据导入导出等等详细过程记录3&#xff0c;嵌入式数据库事务理解以及实例操作4&#xff0c;数据迁移备份--从低版本3.6.2到高版本3…

(原) 我要地图 pk Google地图

要做关于电子地图PK的分析&#xff0c;首先需要给大家介绍一个概念&#xff1a;地标。通俗说来&#xff0c;地标就是地理位置上的标志性物体&#xff0c;可以是建筑&#xff0c;设施&#xff0c;地理位置名称等等。一般来说&#xff0c;地标不会轻易发生变化&#xff0c;就像一…

mycat 不得不说的缘分

1&#xff0c;愕然回首&#xff0c;它在灯火阑珊处关于mysql集群中间件&#xff0c;以前写在应用程序里面&#xff0c;由开发人员实现&#xff0c;在配置文件里面写多个数据源&#xff0c;写库一个数据源&#xff0c;读库一个数据源&#xff0c;笨拙不高效&#xff0c;由于程序…

(转)Google地图API之优劣分析

Google最重要的产品不仅仅是网页搜索和Gmail&#xff0c;Google其实有一个重要的宝贝产品&#xff0c;就是Google Earth/Maps&#xff0c;即卫星地图&#xff08;或常规地图&#xff09;。这个产品如果开发的好的话&#xff0c;可以使得Google在地图领域中建立新的权威优势。 G…

Nginx 访问静态资源报错404 Not Found 的问题解决过程

1、静态资源访问报错404&#xff1a;[nginxdev_121_21 tmp]$ wget http://bsstatic.powerlong.com/commonStatic/css/merchant_patch.css --2016-11-22 18:18:28-- http://bsstatic.powerlong.com/commonStatic/css/merchant_patch.css 正在解析主机 bsstatic.powerlong.c…