MySQL에서 자동 증가 ID 기본 키와 UUID를 기본 키로 사용하는 경우의 장단점을 비교하는 세부 프로세스(100만에서 1000만 개의 테이블 레코드 테스트)

黄舟
풀어 주다: 2017-02-16 11:35:54
원래의
1814명이 탐색했습니다.

테스트 이유

개발 동료가 기본 키가 uuid인 프레임워크를 만들었는데, 나는 그에게 mysql이 uuid를 사용하지 말고 자동 증가 기본 키를 사용하는 것이 더 효율적인 것은 아니라고 제안했습니다. innodb의 인덱스 기능은 id를 자동증가시키는 기능이라 기본키를 만드는 것이 가장 효율적이라고 했고, 실제 사례를 통해 설득하기 위해 상세한 테스트를 준비했습니다.

인터넷 회사라면 사용자 테이블이 있어야 하는데, UC_USER 사용자 테이블은 기본적으로 수백만개 따라서 이 표를 바탕으로 준시험자료를 바탕으로 시험을 진행한다.

현재 테스트 과정은 제가 생각하는 여러 종류의 SQL 테스트가 다면적이고 흔히 사용되는 테스트입니다. 완벽하지 않을 수도 있습니다. 보다 완벽한 테스트 계획이나 테스트 SQL 문을 제안하기 위해 메시지를 남겨주시면 됩니다.

테이블 및 데이터 준비

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 사용

티바디>테이블>

2. 500W데이터 테스트

2.1 500W 입력, 자동 증가 ID 절반 저장 디스크 공간

두 테이블의 데이터 볼륨 결정

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='用户表';

CREATE TABLE `UC_USER_PK_VARCHAR_1`(
`ID` varchar(36) 문자 집합 utf8mb4 NOT NULL 기본값 '0' COMMENT '기본 키', `USER_NAME` varchar(100) 기본 NULL 코멘트 '사용자 이름',
`USER_PWD` varchar(200) 기본 NULL 코멘트 '비밀번호',
`BIRTHDAY` 날짜/시간 기본 NULL 코멘트 '생일', `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` 날짜 시간 DEFAULT CURRENT_TIMESTAMP COMMENT '등록 시간',
`UPDATE_DATE` 날짜 시간 DEFAULT CURRENT_TIMESTAMP COMMENT '수정 날짜',
`PWD_INTENSITY` char(1) DEFAULT NULL COMMENT '비밀번호 강도',
`MOBILE_TGC` char(64) DEFAULT NULL COMMENT '휴대폰 로그인 ID',
`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: 수동 ',
기본 키(`ID`),
고유 키 `USER_NAME`(`USER_NAME`),
키 `MOBILE`(`MOBILE`) ,
키 `IDX_MOBILE_TGC`(`MOBILE_TGC`,`ID`),
키 `IDX_EMAIL`(`EMAIL`,`ID`),
키 `IDX_CREATE_DATE`(`CREATE_DATE`, `ID`),
KEY `IDX_UPDATE_DATE` (`UPDATE_DATE`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='사용자 테이블';

# 自增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가 있는 테이블

mysql> UC_USER에서 count(1) 선택;

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

主键类型

数据文件大小

占据容量

自增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

| 개수( 1) |

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

| 5720112 |

+------- ---+세트의 1행(0.00초) mysql> # uuid가 기본인 테이블 key mysql> UC_USER_PK_VARCHAR_1에서 count(1) 선택;

主键类型

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

+----------+| +--- -------+| 5720112 |+--------+1행 in set (1.91 sec)
차지하는 공간 용량으로 판단하면 자동 증분 ID는 기존보다 절반 정도 작습니다. UUID.
기본 키 유형 데이터 파일 크기 점유 용량 강함>
자체 증가 ID -rw -rw---- 1 mysql mysql 2.5G 8월 11일 18:29 UC_USER.ibd 2.5G
UUID -rw-rw---- 1 mysql mysql 5.4G 8월 15일 15: 11 UC_USER_PK_VARCHAR_1.ibd 5.4G
2.2 단일 데이터를 인덱싱하고 id를 id만큼 증가시킵니다. 그리고 uuid별로 다르지 않습니다자동 증가 ID

0.040

기본 키 유형 SQL 문 td>

실행 시간(초)

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

0.118

UUID 선택 SQL_NO_CACHE t.* FROM 테스트. `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 td> SELECT SQL_NO_CACHE t.* FROM test.`UC_USER_PK_VARCHAR_1` t WHERE t.`MOBILE` IN('14782121512','13761460105');

자동 증가 ID SELECT SQL_NO_CACHE t .* FROM 테스트.`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 Scopelike쿼리, 자동 증가 IDUUID

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 20개 제한; tr>

主键类型

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

기본 키 유형
SQL 문 실행 시간(초)

(1) 퍼지 범위 쿼리 1000개 데이터의 경우 UUID보다 Self-increasing ID의 성능이 더 좋습니다

Self-increasing 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 테스트. `UC_USER_PK_VARCHAR_1` t WHERE t.`MOBILE` LIKE '147%' LIMIT 1000; 3.196 td>
(2) 날짜 범위 20개의 데이터를 쿼리하면 자동으로 증분 ID는 UUID보다 약간 약합니다 td>
자동 증분 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
UUID0.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 테스트.`UC_USER` t WHERE t.`CREATE_DATE` > ' 2016-07-01 10:26:36' ; 0.514
UUID SQL_NO_CACHE 개수 선택(1 ) FROM 테스트.`UC_USER_PK_VARCHAR_1` t WHERE t.`CREATE_DATE` > '2016-07 -01 10:26:36' ; 1.092

PS: 캐시가 있는 경우 둘 사이의 실행 효율성에는 작은 차이가 없습니다.

2.4 쓰기 테스트, 자동 증가 ID 4

기본 키 유형 업데이트 테스트.`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' ;UUIDUPDATE 테스트.`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' ;자동 증가 IDINSERT INTO 테스트.`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, `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;UUID

SQL 문

실행 시간(초)

자동증가ID

1.419

5.639

0.105

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`  100개 제한;

0.424

 

 

 

2.5、备份和恢复,自增ID性能优于UUID

主键类型

SQL语句

执行时间 (秒)

Mysqldump备份

自增ID

time mysqldump -utim -ptimgood -h192.168.121.63 test UC_USER_500> UC_USER_500.sql

28.59秒

UUID

time mysqldump -utim -ptimgood  -h192.168.121.63 test UC_USER_PK_VARCHAR_500> UC_USER_PK_VARCHAR_500.sql

31.08秒

 

MySQL恢复

自增ID

time mysql  -utim -ptimgood -h192.168.121.63  test < UC_USER_500.sql

7m36.601s

UUID

time mysql -utim -ptimgood -h192.168.121.63 test < UC_USER_PK_VARCHAR_500.sql

9m42.472s

<🎜>主键类型 <🎜><🎜 ><🎜><🎜>SQL语句<🎜><🎜><🎜><🎜>执行时间(秒)<🎜><🎜><🎜>< tr>

 <🎜>

Mysqldump备份<🎜><🎜><🎜><🎜><🎜>자체 ID<🎜><🎜><🎜><🎜>time mysqldump -utim -ptimgood  -h192.168.121.63 테스트 UC_USER_500> UC_USER_500.sql28.59秒

UUID시간 mysqldump -utim -ptimgood  -h192.168.121.63 테스트 UC_USER_PK_VARCHAR_500> UC_USER_PK_VARCHAR_500.sql31.08秒

 

MySQL恢复

자체IDtime mysql  -utim -ptimgood -h192.168.121.63  test < UC_USER_500.sql<🎜><🎜><🎜><🎜>7분36.601초<🎜><🎜><🎜><🎜><🎜>UUID<🎜><🎜><🎜><🎜>시간 mysql -utim -ptimgood -h192.168.121.63  테스트 < UC_USER_PK_VARCHAR_500.sql<🎜><🎜><🎜><🎜>9m42.472s<🎜><🎜><🎜><🎜><🎜> <🎜><🎜>< 🎜><🎜> <🎜><🎜><🎜><🎜> <🎜><🎜><🎜><🎜><🎜>

3, 500W요약

500W 레코드 테이블 테스트:

(1) 일반 단일 또는 약 20개 레코드 검색의 경우 uuid가 기본 키입니다. 효율성은 거의 같습니다.

(2) 그러나 범위 쿼리의 경우, 특히 수백 또는 수천 개의 레코드에 대해서는 자동 증가 ID의 효율성이 uuid보다 큽니다.

(3) 범위 쿼리에서 통계를 요약하면 자체 증가 ID의 효율성이 uuid보다 큽니다.

(4) 저장 측면에서 자체 증가 ID가 차지하는 저장 공간은 uuid의 1/2입니다.

(5 ) 백업 및 복구 측면에서 자동 증가 ID 기본 키는 UUID보다 약간 더 좋습니다.

41000W데이터 테스트

4.1 입력1000W데이터기록, 저장공간 참고

# 自增id为主键的表

mysql> use test;

Database changed

mysql> select count(1) from UC_USER_1;

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

| count(1) |

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

| 10698102 |

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

1 row in set (27.42 sec)

 

# uuid为主键的表

mysql> select count(1) from  UC_USER_PK_VARCHAR_1;

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

| count(1) |

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

| 10698102 |

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

1 row in set (0.00 sec)

 

mysql>

#

자체 증분

id 기본 키로 테이블

主键类型

数据文件大小

占据容量 

自增ID

-rw-rw---- 1 mysql mysql 4.2G Aug 20  23:08 UC_USER_1.ibd

4.2 G

UUID

-rw-rw---- 1 mysql mysql 8.8G Aug 20  18:20 UC_USER_PK_VARCHAR_1.ibd

8.8 G

mysql> use test;데이터베이스 변경됨mysql> UC_USER_1에서 count(1) 선택;+ - ----------+| 개수(1) |+----------+| |+----------+1행 세트(27.42초) # uuid 기본 키가 있는 테이블mysql> UC_USER_PK_VARCHAR_1에서 count(1) 선택;+---------+ | 개수(1) |+----------+| 10698102 |+------- -- -+세트의 1개 행(0.00초) mysql>
점유된 공간 용량으로 볼 때 자동 증가 ID는 UUID보다 절반 정도 작습니다. 자동 증가 ID
기본 키 유형 데이터 파일 크기 점유 용량
-rw-rw---- 1 mysql mysql 4.2G 8월 20일 23:08 UC_USER_1 .ibd 4.2G
UUID -rw-rw---- 1 mysql mysql 8.8G 8월 20일 18:20 UC_USER_PK_VARCHAR_1.ibd td> 8.8G

4.2 단일 데이터는 인덱스로 조회, 자동 증분id uuid 사이의 효율성 비율은 다음과 같습니다. (2~3):1

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

날짜 기준 쿼리

主键类型

SQL语句

执行时间 (秒)

 

单条记录查询

自增ID

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

0.069

UUID

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

0.274

 

小范围查询

自增ID

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

0.050

UUID

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

0.151

 

根据日期查询

自增ID

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

0.269

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.810

기본 키 유형
SQL 문

실행 시간(초) )

단일 레코드 쿼리

자동 증가 ID

0.069

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

0.274

작은 범위 쿼리

자체 증가 ID SELECT SQL_NO_CACHE t.* FROM test.`UC_USER_1` t WHERE t.`MOBILE` IN( '14782121512',' 13761460105');

0.050

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

0.151

자동 증가 ID SELECT SQL_NO_CACHE t .* FROM 테스트.`UC_USER_1` t WHERE t.`CREATE_DATE`='2013-11-24 10:26:36' ;

0.269

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.810

4.3 Scopelike쿼리, 자동 증가 IDUUID, ratio(1.5~2)보다 성능이 뛰어납니다.1

tr>자동 증가 ID UUID2.302

主键类型

SQL语句

执行时间 (秒)

 

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

自增ID

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

2.398

UUID

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

5.872

 

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

自增ID

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

0.765

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;

1.090

 

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

自增ID

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

1.569

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;

2.597

 

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

自增ID

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

1.129

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'   ;

2.302

기본 키 유형
SQL 문 실행 시간(초)

(1) 퍼지 범위 쿼리 1000개 데이터, 자동 증가 ID 성능이 UUID보다 우수함 td>

자동 증가 ID SELECT SQL_NO_CACHE t.* FROM 테스트. `UC_USER` t WHERE t .`MOBILE` LIKE '147%' LIMIT 1000; 2.398
UUID SELECT SQL_NO_CACHE t.* FROM test.`UC_USER_PK_VARCHAR_1` t WHERE t.`MOBILE` LIKE '147%' 제한 1000 ; 5.872
(2) 해당 날짜 범위의 데이터를 20개 쿼리하고, 자동 증가 ID가 UUID보다 약간 약함
자동 증가 ID SELECT SQL_NO_CACHE t.* FROM test.`UC_USER_1` t WHERE t.`CREATE_DATE` > '2016-08-01 10:26:36' ORDER BY t.`UPDATE_DATE` DESC LIMIT 20; 0.765
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; 1.090
(3) 범위 쿼리 200개 데이터, 자동 증가 ID 성능이 UUID보다 우수함
자동 증가 ID td> SELECT SQL_NO_CACHE t.* FROM test.`UC_USER_1` t WHERE t.`CREATE_DATE` > '2016-07-01 10:26:36' ORDER BY t.` 업데이트_날짜` DESC 제한 200; 1.569
UUID SELECT SQL_NO_CACHE t.* FROM test.`UC_USER_PK_VARCHAR_1` t WHERE t.`CREATE_DATE` > ' ORDER BY t.`UPDATE_DATE` DESC LIMIT 200; 2.597
범위 쿼리 총 수량, 자동 증가 ID가 UUID보다 좋음
SELECT SQL_NO_CACHE COUNT(1) FROM test.`UC_USER_1` t WHERE t.`CREATE_DATE ` > '2016-07-01 10:26:36' ; td> 1.129
SELECT SQL_NO_CACHE COUNT(1) FROM test.`UC_USER_PK_VARCHAR_1` t WHERE t.`CREATE_DATE` > '2016-07-01 10:26:36' ;

4.4 쓰기 테스트, 자동 증가 ID UUID보다 효율적이고 비율은 (3~10): 1

기본 키 유형

SQL 문

실행 시간(초)

하루의 기록 수정

ID증가

업데이트 테스트.`UC_USER_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' ;

2.685

UUID

UPDATE 테스트.`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' ;

26.521

데이터 입력

자동 증가 ID

INSERT INTO 테스트`UC_USER_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`, `MO BILE`, `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 ; `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.534

UUID

INSERT INTO 테스트.`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`,   `ACTIV ATE`,   `ACTIVATE_TYPE` FROM `test`.`UC_USER_1`  한도 100;

1.716

 

 

 

4.5、备份和恢复,自增ID性能优于UUID

主键类型

SQL语句

执行时间 (秒)

Mysqldump备份

自增ID

time mysqldump -utim -ptimgood -h192.168.121.63 test UC_USER_1> UC_USER_1.sql

0m50.548s

UUID

time mysqldump -utim -ptimgood  -h192.168.121.63 test UC_USER_PK_VARCHAR_1> UC_USER_PK_VARCHAR_1.sql

0m58.590s

 

MySQL恢复

自增ID

time mysql -utim -ptimgood  -h192.168.121.63 test < UC_USER_1.sql

17m30.822s

UUID

time mysql -utim -ptimgood -h192.168.121.63 test < UC_USER_PK_VARCHAR_1.sql

23m6.360s

<🎜>主键类型 <🎜><🎜 ><🎜><🎜>SQL语句<🎜><🎜><🎜><🎜>执行时间(秒)<🎜><🎜><🎜>< tr>

 <🎜>

Mysqldump备份<🎜><🎜><🎜><🎜><🎜>자체 ID<🎜><🎜><🎜><🎜>time mysqldump -utim -ptimgood -h192.168.121.63  UC_USER_1 테스트> UC_USER_1.sql0m50.548s

UUID시간 mysqldump -utim -ptimgood  -h192.168.121.63 test UC_USER_PK_VARCHAR_1> UC_USER_PK_VARCHAR_1.sql0m58.590s

 

MySQL 지원

自增IDtime mysql -utim -ptimgood  -h192.168.121.63 test < UC_USER_1.sql<🎜><🎜><🎜><🎜>17분30.822초<🎜><🎜><🎜><🎜><🎜>UUID<🎜><🎜><🎜><🎜>시간 mysql -utim -ptimgood  -h192.168.121.63 test < UC_USER_PK_VARCHAR_1.sql<🎜><🎜><🎜><🎜>23분6.360초<🎜><🎜><🎜><🎜><🎜> <🎜><🎜>< 🎜><🎜> <🎜><🎜><🎜><🎜> <🎜><🎜><🎜><🎜><🎜>

5, 1000W요약

1000W 레코드 테이블 테스트:

(1) 일반적인 단일 또는 약 20개 레코드 검색의 경우 자동 증가 기본 키의 효율성은 2~3배입니다. uuid 기본 키

(2) 그러나 범위 쿼리의 경우, 특히 수백 또는 수천 개의 레코드에 대해서는 자동 증가 ID의 효율성이 uuid보다 큽니다.

(3) 범위 쿼리에 대한 통계 요약을 수행할 때 자동 증가 ID 기본 키의 효율성은 uuid 기본 키의 1.5~2배입니다.

(4) 저장 측면에서 보면, 자동 증가 ID는 uuid의 1/2입니다.

( 5) 쓰기 측면에서 자동 증가 ID 기본 키의 효율성은 UUID 기본 키의 3~10배입니다. 이는 특히 작은 범위 내에서 데이터를 업데이트할 때 분명합니다.

(6) 백업 및 복구 측면에서는 자체 증가 ID 기본 키가 UUID보다 약간 더 좋습니다.

6, MySQL분산 아키텍처 절충

분산 아키텍처는 테이블의 기본 키의 고유성이 여러 인스턴스에서 유지되어야 함을 의미합니다. 현재 일반 단일 테이블 자체 증가 ID 기본 키는 적합하지 않습니다. 여러 mysql 인스턴스에서 기본 키의 전역 고유성 문제가 발생하기 때문입니다.

6.1, 자동증가 ID 기본 키 + 단계 크기, 중간 규모 분산 시나리오에 적합

각 클러스터 노드 그룹의 마스터에서, (auto_increment_increment)를 설정하고, 각 클러스터의 현재 시작점을 1씩 엇갈리게 하고, 미래에 기본적으로 달성할 수 없는 분할 클러스터 수보다 더 큰 단계 크기를 선택하여 ID를 상대적으로 분할하는 효과를 얻습니다. 글로벌 고유 효과를 만나보세요.

장점은 간단한 구현, 간단한 사후 유지 관리, 애플리케이션 투명성입니다.

단점: 향후 비즈니스 개발을 위해 충분한 단계 크기를 계산해야 하기 때문에 첫 번째 설정이 상대적으로 복잡합니다. ;

계획:

예를 들어 총 N개의 노드 그룹이 계획된 경우 i- my.cnf의 구성은 다음과 같습니다.

auto_increment_offset i

auto_increment_increment N

48개의 노드 그룹이 계획된 경우 N은 48입니다. 이제 8번째 노드 그룹을 구성합니다. i는 8입니다. 8번째 노드 그룹의 my.cnf 구성은

auto_increment_offset 8

auto_increment_increment 48

입니다.

6.2, UUID, 소규모 분산 환경에 적합

InnoDB와 같은 클러스터형 기본 키 유형 엔진의 경우 UUID의 무질서로 인해 데이터가 기본 키에 따라 정렬되며 InnoDB는 엄청난 IO 압력을 발생시키고 인덱스와 데이터가 함께 저장되기 때문에 , 문자열은 기본 키로 인해 저장 공간이 두 배로 늘어납니다.

innodb는 저장 및 검색 중에 기본 키를 물리적으로 정렬합니다. 이는 나중에 삽입되는 기본 키의 위치가 항상 끝에 있기 때문에 auto_increment_int에 좋은 소식입니다. 하지만 uuid의 경우 이는 나쁜 소식입니다. 왜냐하면 uuid는 지저분하고 매번 삽입되는 기본 키의 위치가 불확실하기 때문입니다. 기본 키를 물리적으로 정렬할 때 필연적으로 발생할 수 있는 문제가 있습니다. 많은 수의 IO 작업은 효율성에 영향을 미칩니다. 데이터 양이 계속 증가하면, 특히 데이터 양이 수천만 개의 레코드를 초과하는 경우 읽기 및 쓰기 성능이 급격히 떨어집니다.

장점: 구성이 비교적 간단하고 기본 키의 고유성이 필요하지 않습니다.

단점: 저장 공간을 두 배로 차지합니다(클라우드 저장소 한 개에 대해 2배 더 많은 비용 발생). 나중에 읽기 쓰기 성능이 급격히 떨어집니다.

6.3, Snowflake 알고리즘은 전역 자체 생성 made 빅데이터 환경의 분산 시나리오에 적합한 ID 추가

트위터에서 발표한 오픈소스 분산 ID 알고리즘 눈송이(Java 버전)

IdWorker.java:

package com.demo.elk;

org.slf4j.Logger 가져오기

org.slf4j.LoggerFactory 가져오기;

     보호된 정적 최종 로거 LOG =  LoggerFactory.getLogger(IdWorker.class);

    

     private long WorkerId;

     private long datacenterId;

private long 시퀀스 = 0L;

 

     private long twepoch = 1288834974657L;

 

     private long WorkerIdBits = 5L;

     priv 오래 먹었다 datacenterIdBits = 5L;

     private long maxWorkerId = -1L ^ (-1L <

     private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);

<<> 개인 긴 시퀀스 비트 = 12L;

개인 Long WorkerIdshift = SequenceBits;

개인 Long DatacenterIdShift = SequenceBits + WorkerIdbits; <🎜

<🎜 🎜> private long timestampLeftShift = sequenceBits + WorkerIdBits +  datacenterIdBits;

     private long sequenceMask = -1L ^ (-1L << 시퀀스Bits);

 

     private long lastTimestamp = - 1L;

 

     public IdWorker(긴 작업자 ID, 긴 데이터 센터 ID) {

         // 작업자 ID

에 대한 온전성 검사         if (workerId > maxWorkerId || 작업자 ID < 0) {

            새로운  IllegalArgumentException(String.format("작업자 ID는  %d보다 크거나 0보다 작을 수 없습니다.", maxWorkerId));

         }

         if (datacenterId > maxDatacenterId || datacenterId < 0) {

             throw new  IllegalArgumentException(String.format("datacenter Id can't be less than %d or less than 0", maxDatacenterId));

         }

         this.workerId = WorkerId;

         this.datacenterId = datacenterId;

         LOG.info(String.format("작업자 시작 시간. 앰프 왼쪽 시프트 %d,  데이터센터 ID 비트 %d, 작업자 ID 비트 %d, 시퀀스 비트 %d, 작업자 ID  %d", timestampLeftShift, datacenterIdBits, WorkerIdBits, SequenceBits,  workerId));

     }

 

     공개 동기화된 긴 nextId() {

         long timestamp = timeGen();

 

         if (timestamp < lastTimestamp) {

             LOG.error(String.format("시계가 뒤로 이동 중입니다.  %d까지 요청을 거부합니다.",  lastTimestamp));

            throw new  RuntimeException(String.format("시계가 뒤로 이동했습니다.  %d  밀리초 동안 ID 생성 거부", lastTimestamp - timestamp));

         }

 

        if (lastTimestamp == timestamp) {

            시퀀스 = (시퀀스 + 1) &  sequenceMask;

            if (시퀀스 == 0) {

               timestamp =  tilNextMillis(lastTimestamp);

           }

         } else {

            시퀀스 = 0L;

         }

 

        lastTimestamp = 타임스탬프;

 

         반환(( timestamp - twepoch) << timestampLeftShift) |   (datacenterId << datacenterIdShift) | (workerId

    }

 

protected long tilNextMillis(long lastTimestamp) {

         long timestamp = timeGen();

         while (timestamp <= lastTimestamp) {

            timestamp = timeGen();

         }

         return timestamp;

     }

 

     보호된 오랜 시간Gen() {

         return  System.currentTimeMillis();

     }

}

 

 

 

测试生成ID 测试类,IdWorkerTest.java:

package com.demo.elk;

import java.util.HashSet;

import java.util.Set;

public class IdWorkerTest {

static class IdWorkThread implements Runnable {

private Set set;

         private IdWorker idWorker;

 

         public IdWorkThread(Set set, IdWorker idWorker) {

            this.set = set;

            this.idWorker = idWorker;

         }

 

         public void run() {

            while (true) {

                 long id =  idWorker.nextId();

                 System.out.println("             real id:" + id);

                if (!set.add(id)) {

                     System.out.println("duplicate:" + id);

                }

            }

         }

     }

 

     public static void main(String[] args) {

         Set set = new HashSet();

         final IdWorker idWorker1 = new IdWorker(0, 0);

         final IdWorker idWorker2 = new IdWorker(1, 0);

         Thread t1 = new Thread(new IdWorkThread(set, idWorker1));

        Thread t2 = new Thread(new  IdWorkThread(set, idWorker2));

         t1.setDaemon(true);

         t2.setDaemon(true);

         t1.start();

         t2.start();

         try {

            Thread.sleep(30000);

         } catch (InterruptedException e) {

             e.printStackTrace();

         }

     }

}

package com.demo.elk; java.util.HashSet 가져오기;java.util 가져오기. Set; public class IdWorkerTest {               정적 클래스 IdWorkThread는 Runnable을 구현합니다. {         private Set set;         private IdWorker idWorker;          public IdWorkThread(Set set, IdWorker idWorker) {           this.set = 설정;           this.idWorker = idWorker;         }          public void run() {            동안(tru 전자) {                 긴 ID =  idWorker.nextId();                System.out.println("            실제 ID:" + id);                if (!set.add(id)) {                    System.out.println("duplicate:" + id);              }           }         }     }      public static void main(String[] args) {         Set set = new HashSet();         final IdWorker idWorker1 = new IdWorker(0, 0);         final IdWorker idWorker2 = new IdWorker(1, 0);         스레드 t1 = new Thread(new IdWorkThread(set, idWorker1));        스레드 t2 = new Thread(new  IdWorkThread(set, idWorker2));         t1.setDaemon(true) ;         t2.setDaemon(true);         t1.start();         t2.start();         시도해 보세요 {            Thread.sleep(30000);         } catch (InterruptedException e) {             e.printTrace();         }      }}

7, 요약

(1) 단일 인스턴스 또는 단일 노드 그룹:

500W 및 1000W 독립형 테이블 테스트 후 자동 증가 ID가 UUID보다 낫습니다. 증분 ID 기본 키의 성능은 UUID보다 높으며 디스크 저장 비용은 UUID의 절반입니다. 따라서 단일 인스턴스 또는 단일 노드 그룹에서 자동 증가 ID를 기본 기본 키로 사용합니다.

(2) 분산 아키텍처 시나리오:

20개 노드 그룹의 소규모 분산 시나리오에서는 UUID 기본 키를 다중 꽃 저장 비용으로 빠르게 배포할 수 있으며

20~200개의 노드 그룹이 있는 중간 규모 분산 시나리오의 경우 자체 증가 ID + 단계 크기의 더 빠른 솔루션을 사용할 수 있습니다.

노드 그룹이 200개 이상인 빅데이터의 분산 시나리오는 Twitter Snowflake 알고리즘에 의해 생성된 전역 자동 증가 ID를 기본 키로 학습할 수 있습니다.

위는 MySQL에서 Auto-incrementing ID 기본키와 UUID를 기본키로 사용할 때의 장단점을 자세하게 비교하는 과정이다. 수천만 개의 테이블 레코드까지). 더 많은 관련 내용을 보려면 PHP 중국어 웹사이트(www.php.cn)를 주목하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿