MySQL 使用自增ID主鍵和UUID 作為主鍵的優劣比較詳細過程(500W單表)
一個開發同事做了一個框架,裡面主鍵是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 '主鍵',
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小一半左右。
3、總結 在500W記錄表的測試下:
(1) 普通單條或者20條左右的記錄檢索,uuid為主鍵的相差不大幾乎效率相同;
(2) 但是範圍查詢特別是上百成千條的記錄查詢,自增id的效率要大於uuid;
(3) 在範圍查詢做統計彙總的時候,自增id的效率要大於uuid;
(4) 在儲存上面,自增id所佔的儲存空間是uuid的1/2;(int佔4個位元組,uuid佔3個位元組)
--------------------------------------------------------------------------------------------------------------------------