테스트 이유
개발 동료가 기본 키가 uuid인 프레임워크를 만들었는데, mysql에서는 uuid를 사용하지 말고 자동 증가 기본 키를 사용하는 것이 더 효율적이라고 제안했습니다. 꼭 높을 필요는 없다고 말씀드렸고, innodb index 기능을 통해 자동증가 ID를 기본키로 사용하는 것이 가장 효율적이게 되었습니다. 그를 설득하기 위해 자세한 테스트를 준비했습니다.
인터넷 회사라면 사용자 테이블이 있어야 하는데, UC_USER 사용자 테이블은 기본적으로 수백만개 따라서 이 표를 바탕으로 준시험자료를 바탕으로 시험을 진행한다.
대략적인 환경은 Centos6.5, MySQL5.6.12
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 테스트.` 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` > -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 | SELECT SQL_NO_CACHE COUNT(1) FROM 테스트 .`UC_USER_PK_VARCHAR_1` t WHERE t.`CREATE_DATE` > '2016-07 -01 10:26:36' ; | 1.092 td> |
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_ 날짜`, `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개 제한; |
0.424 |
지금500W记录表下:
(1) 普通单条或者20条左右的记录检索,uuid为主键 的 相差不大几乎效率同;
(2) 但是范围查询特别是上百成千条的记录查询,自增id的效率要大于uuid;
(3) 在范围查询做统计汇总的时候,自增id的效率要大于uuid;
(4) 재存储上面,自增id所?的存储空间是uuid的1/2;
以上就是MySQL 使用自增ID主键와UUID 가 为主键的优劣比较详전력 소비량(500W)单表)的内容,更多敳关内容请关注PHP中文网(www.php.cn)!