테스트 이유
개발 동료가 기본 키가 uuid인 프레임워크를 만들었는데, 나는 그에게 mysql이 uuid를 사용하지 말고 자동 증가 기본 키를 사용하는 것이 더 효율적인 것은 아니라고 제안했습니다. innodb의 인덱스 기능은 id를 자동증가시키는 기능이라 기본키를 만드는 것이 가장 효율적이라고 했고, 실제 사례를 통해 설득하기 위해 상세한 테스트를 준비했습니다.
인터넷 회사라면 사용자 테이블이 있어야 하는데, UC_USER 사용자 테이블은 기본적으로 수백만개 따라서 이 표를 바탕으로 준시험자료를 바탕으로 시험을 진행한다.
현재 테스트 과정은 제가 생각하는 여러 종류의 SQL 테스트가 다면적이고 흔히 사용되는 테스트입니다. 완벽하지 않을 수도 있습니다. 보다 완벽한 테스트 계획이나 테스트 SQL 문을 제안하기 위해 메시지를 남겨주시면 됩니다.
UC_USER, 기본 키로 자동 증가 ID, 테이블 구조는 다음과 유사합니다.
CREATE TABLE `UC_USER` ( |
UC_USER_PK_VARCHAR 테이블, 기본 키로 문자열 ID, uuid 사용
`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='사용자 테이블'; |
| 개수( 1) | +----------+ | 5720112 | +------- ---+세트의 1행(0.00초) mysql> # uuid가 기본인 테이블 key mysql> UC_USER_PK_VARCHAR_1에서 count(1) 선택;
|
기본 키 유형 | 데이터 파일 크기 | 점유 용량 강함> |
자체 증가 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 |
기본 키 유형 | 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 |
|
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 | |||||||||||||||||||||||||||||||||||||||
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 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 | tr>|||||||||||||||||||||||||||||||||||||||
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: 캐시가 있는 경우 둘 사이의 실행 효율성에는 작은 차이가 없습니다.
SQL 문 |
실행 시간(초) |
|
||
|
|
자동증가ID | 업데이트 테스트.`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 테스트.`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 테스트.`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; | ||
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` 100개 제한; | 0.424 |
主键类型 | 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 |
|
|
|
<🎜>
Mysqldump备份<🎜><🎜><🎜>
MySQL恢复
500W 레코드 테이블 테스트:
(1) 일반 단일 또는 약 20개 레코드 검색의 경우 uuid가 기본 키입니다. 효율성은 거의 같습니다.
(2) 그러나 범위 쿼리의 경우, 특히 수백 또는 수천 개의 레코드에 대해서는 자동 증가 ID의 효율성이 uuid보다 큽니다.
(3) 범위 쿼리에서 통계를 요약하면 자체 증가 ID의 효율성이 uuid보다 큽니다.
(4) 저장 측면에서 자체 증가 ID가 차지하는 저장 공간은 uuid의 1/2입니다.
(5 ) 백업 및 복구 측면에서 자동 증가 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 |
|
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 테스트.`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 문 | 실행 시간(초) | |||||||||||||||||||||||||||||||||||||||
(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보다 약간 약함 | tr>|||||||||||||||||||||||||||||||||||||||||
자동 증가 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' ; | 2.302
기본 키 유형 |
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 |
主键类型 | 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 |
|
|
|
<🎜>
Mysqldump备份<🎜><🎜><🎜>
MySQL 지원
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보다 약간 더 좋습니다.
분산 아키텍처는 테이블의 기본 키의 고유성이 여러 인스턴스에서 유지되어야 함을 의미합니다. 현재 일반 단일 테이블 자체 증가 ID 기본 키는 적합하지 않습니다. 여러 mysql 인스턴스에서 기본 키의 전역 고유성 문제가 발생하기 때문입니다.
각 클러스터 노드 그룹의 마스터에서, (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
입니다.
InnoDB와 같은 클러스터형 기본 키 유형 엔진의 경우 UUID의 무질서로 인해 데이터가 기본 키에 따라 정렬되며 InnoDB는 엄청난 IO 압력을 발생시키고 인덱스와 데이터가 함께 저장되기 때문에 , 문자열은 기본 키로 인해 저장 공간이 두 배로 늘어납니다.
innodb는 저장 및 검색 중에 기본 키를 물리적으로 정렬합니다. 이는 나중에 삽입되는 기본 키의 위치가 항상 끝에 있기 때문에 auto_increment_int에 좋은 소식입니다. 하지만 uuid의 경우 이는 나쁜 소식입니다. 왜냐하면 uuid는 지저분하고 매번 삽입되는 기본 키의 위치가 불확실하기 때문입니다. 기본 키를 물리적으로 정렬할 때 필연적으로 발생할 수 있는 문제가 있습니다. 많은 수의 IO 작업은 효율성에 영향을 미칩니다. 데이터 양이 계속 증가하면, 특히 데이터 양이 수천만 개의 레코드를 초과하는 경우 읽기 및 쓰기 성능이 급격히 떨어집니다.
장점: 구성이 비교적 간단하고 기본 키의 고유성이 필요하지 않습니다.
단점: 저장 공간을 두 배로 차지합니다(클라우드 저장소 한 개에 대해 2배 더 많은 비용 발생). 나중에 읽기 쓰기 성능이 급격히 떨어집니다.
트위터에서 발표한 오픈소스 분산 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); <🎜 🎜> 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 } timestamp = timeGen(); } return timestamp; } 보호된 오랜 시간Gen() { return System.currentTimeMillis(); } } |
测试生成ID 测试类,IdWorkerTest.java:
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)를 주목하세요!
성명: 본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요. |