MySQL 성능 최적화 신기 Explain 의 기본 사용 분석
MySQL 은 개발 자 들 이 맞 춤 형 최 적 화 를 위해 SELECT 문 구 를 분석 하고 SELECT 가 실행 하 는 상세 한 정 보 를 출력 할 수 있 는 EXPLAIN 명령 을 제공 합 니 다.
EXPLAIN 명령 의 용법 은 매우 간단 합 니 다.SELECT 문구 앞 에 Explain 을 추가 하면 됩 니 다.예 를 들 어:
EXPLAIN SELECT * from user_info WHERE id < 300;
준비 하 다.다음 에 EXPLAIN 의 사용 을 편리 하 게 보 여주 기 위해 서 는 먼저 두 개의 테스트 용 표를 만 들 고 해당 하 는 데 이 터 를 추가 해 야 합 니 다.
CREATE TABLE `user_info` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL DEFAULT '',
`age` INT(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `name_index` (`name`)
)
ENGINE = InnoDB
DEFAULT CHARSET = utf8
INSERT INTO user_info (name, age) VALUES ('xys', 20);
INSERT INTO user_info (name, age) VALUES ('a', 21);
INSERT INTO user_info (name, age) VALUES ('b', 23);
INSERT INTO user_info (name, age) VALUES ('c', 50);
INSERT INTO user_info (name, age) VALUES ('d', 15);
INSERT INTO user_info (name, age) VALUES ('e', 20);
INSERT INTO user_info (name, age) VALUES ('f', 21);
INSERT INTO user_info (name, age) VALUES ('g', 23);
INSERT INTO user_info (name, age) VALUES ('h', 50);
INSERT INTO user_info (name, age) VALUES ('i', 15);
CREATE TABLE `order_info` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`user_id` BIGINT(20) DEFAULT NULL,
`product_name` VARCHAR(50) NOT NULL DEFAULT '',
`productor` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `user_product_detail_index` (`user_id`, `product_name`, `productor`)
)
ENGINE = InnoDB
DEFAULT CHARSET = utf8
INSERT INTO order_info (user_id, product_name, productor) VALUES (1, 'p1', 'WHH');
INSERT INTO order_info (user_id, product_name, productor) VALUES (1, 'p2', 'WL');
INSERT INTO order_info (user_id, product_name, productor) VALUES (1, 'p1', 'DX');
INSERT INTO order_info (user_id, product_name, productor) VALUES (2, 'p1', 'WHH');
INSERT INTO order_info (user_id, product_name, productor) VALUES (2, 'p5', 'WL');
INSERT INTO order_info (user_id, product_name, productor) VALUES (3, 'p3', 'MA');
INSERT INTO order_info (user_id, product_name, productor) VALUES (4, 'p1', 'WHH');
INSERT INTO order_info (user_id, product_name, productor) VALUES (6, 'p1', 'WHH');
INSERT INTO order_info (user_id, product_name, productor) VALUES (9, 'p8', 'TE');
EXPLAIN 출력 형식EXPLAIN 명령 의 출력 내용 은 다음 과 같 습 니 다.
mysql> explain select * from user_info where id = 2\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user_info
partitions: NULL
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 8
ref: const
rows: 1
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.00 sec)
각 열의 의 미 는 다음 과 같다.select_type
mysql> explain select * from user_info where id = 2\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user_info
partitions: NULL
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 8
ref: const
rows: 1
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.00 sec)
만약 에 저희 가 UNION 조 회 를 사용 했다 면 EXPLAIN 출력 결 과 는 다음 과 같 습 니 다.
mysql> EXPLAIN (SELECT * FROM user_info WHERE id IN (1, 2, 3))
-> UNION
-> (SELECT * FROM user_info WHERE id IN (3, 4, 5));
+----+--------------+------------+------------+-------+---------------+---------+---------+------+------+----------+-----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------+------------+------------+-------+---------------+---------+---------+------+------+----------+-----------------+
| 1 | PRIMARY | user_info | NULL | range | PRIMARY | PRIMARY | 8 | NULL | 3 | 100.00 | Using where |
| 2 | UNION | user_info | NULL | range | PRIMARY | PRIMARY | 8 | NULL | 3 | 100.00 | Using where |
| NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+----+--------------+------------+------------+-------+---------------+---------+---------+------+------+----------+-----------------+
3 rows in set, 1 warning (0.00 sec)
table조회 와 관련 된 표 또는 파생 표
type
type 필드 는 비교적 중요 합 니 다.이것 은 조회 의 효율 성 여 부 를 판단 하 는 중요 한 근 거 를 제공 합 니 다.type 필드 를 통 해 우 리 는 이번 조회 가 전체 표 스 캔 인지 색인 스 캔 인지 판단 합 니 다.
type 상용 형식
type 에서 자주 사용 하 는 값 은:
예 를 들 어 아래 의 이 조 회 는 메 인 키 색인 을 사 용 했 기 때문에 type 은 const 형식 입 니 다.
mysql> explain select * from user_info where id = 2\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user_info
partitions: NULL
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 8
ref: const
rows: 1
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.00 sec)
mysql> EXPLAIN SELECT * FROM user_info, order_info WHERE user_info.id = order_info.user_id\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: order_info
partitions: NULL
type: index
possible_keys: user_product_detail_index
key: user_product_detail_index
key_len: 314
ref: NULL
rows: 9
filtered: 100.00
Extra: Using where; Using index
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: user_info
partitions: NULL
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 8
ref: test.order_info.user_id
rows: 1
filtered: 100.00
Extra: NULL
2 rows in set, 1 warning (0.00 sec)
mysql> EXPLAIN SELECT * FROM user_info, order_info WHERE user_info.id = order_info.user_id AND order_info.user_id = 5\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user_info
partitions: NULL
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 8
ref: const
rows: 1
filtered: 100.00
Extra: NULL
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: order_info
partitions: NULL
type: ref
possible_keys: user_product_detail_index
key: user_product_detail_index
key_len: 9
ref: const
rows: 1
filtered: 100.00
Extra: Using index
2 rows in set, 1 warning (0.01 sec)
예 를 들 어 아래 의 예 는 하나의 범위 조회 이다.
mysql> EXPLAIN SELECT *
-> FROM user_info
-> WHERE id BETWEEN 2 AND 8 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user_info
partitions: NULL
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 8
ref: NULL
rows: 7
filtered: 100.00
Extra: Using where
1 row in set, 1 warning (0.00 sec)
예 를 들 면:
mysql> EXPLAIN SELECT name FROM user_info \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user_info
partitions: NULL
type: index
possible_keys: NULL
key: name_index
key_len: 152
ref: NULL
rows: 10
filtered: 100.00
Extra: Using index
1 row in set, 1 warning (0.00 sec)
위의 예 에서 우리 가 조회 한 name 필드 는 마침 색인 이기 때문에 우 리 는 색인 에서 데 이 터 를 직접 얻 으 면 조회 의 수 요 를 만족 시 킬 수 있 습 니 다.표 의 데 이 터 를 조회 하지 않 아 도 됩 니 다.따라서 type 의 값 은 index 이 고 Extra 의 값 은 Using index 입 니 다.
mysql> EXPLAIN SELECT age FROM user_info WHERE age = 20 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user_info
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 10
filtered: 10.00
Extra: Using where
1 row in set, 1 warning (0.00 sec)
type 유형의 성능 비교일반적으로 type 유형의 성능 관 계 는 다음 과 같 습 니 다.
ALL < index < range ~ index_merge < ref < eq_ref < const < system
ALL 형식 은 전체 표 스 캔 이기 때문에 같은 조회 조건 에서 속도 가 가장 느 립 니 다.
index 형식의 조 회 는 전체 표 스 캔 은 아니 지만 모든 색인 을 스 캔 했 기 때문에 ALL 형식 보다 조금 빠 릅 니 다.
뒤의 몇 가지 유형 은 모두 색인 을 이용 하여 데 이 터 를 조회 하기 때문에 부분 이나 대부분의 데 이 터 를 걸 러 낼 수 있 기 때문에 조회 효율 이 비교적 높다.
possible_keys
possible_keys 는 MySQL 이 검색 할 때 사용 할 수 있 는 색인 을 표시 합 니 다.일부 색인 이 possible 에 있 더 라 도 주의 하 십시오.keys 에 나타 나 지만 이 색인 이 실제로 MySQL 에 사 용 될 지 는 표시 되 지 않 습 니 다.MySQL 은 검색 할 때 어떤 색인 을 사 용 했 는 지 키 필드 에서 결정 합 니 다.
key
이 필드 는 MySQL 이 현재 검색 할 때 사용 하 는 색인 입 니 다.
key_len
검색 유 틸 리 티 가 색인 을 사용 한 바이트 수 를 표시 합 니 다.이 필드 는 조합 색인 이 완전히 사용 되 었 는 지,아니면 가장 왼쪽 필드 만 사용 되 었 는 지 평가 할 수 있 습 니 다.
key_len 의 계산 규칙 은 다음 과 같다.
문자열
우 리 는 간단 한 밤 두 개 를 들 었 다.
mysql> EXPLAIN SELECT * FROM order_info WHERE user_id < 3 AND product_name = 'p1' AND productor = 'WHH' \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: order_info
partitions: NULL
type: range
possible_keys: user_product_detail_index
key: user_product_detail_index
key_len: 9
ref: NULL
rows: 5
filtered: 11.11
Extra: Using where; Using index
1 row in set, 1 warning (0.00 sec)
위의 예 는 표 orderinfo 에서 지정 한 내용 을 조회 합 니 다.이 표 의 작성 표 문 에서 알 수 있 습 니 다.표 orderinfo 에 연합 색인 이 있 습 니 다:
KEY `user_product_detail_index` (`user_id`, `product_name`, `productor`)
하지만 이 검색 어 WHERE userid < 3 AND product_name='p1'AND produtor='WHH'에서 user 를 먼저 진행 하기 때문에id 의 범위 조 회 는 가장 왼쪽 접두사 일치 원칙 에 따라 범위 조 회 를 만 났 을 때 색인 일치 가 중단 되 기 때문에 실제 우리 가 사용 하 는 색인 필드 는 user 밖 에 없습니다.id,따라서 EXPLAIN 에 표 시 된 keylen 은 9.user 때문에id 필드 는 BIGINT 로 8 바이트 가 차지 하고 NULL 속성 은 하나의 바이트 가 차지 하기 때문에 모두 9 바이트 입 니 다.만약 우리 가 userid 필드 를 BIGINT(20)NOT NULL DEFAULT'0'으로 변경 하면 keylength 는 8 일 거 예요.위 에서 가장 왼쪽 접두사 가 일치 하 는 원칙 때문에 우리 의 조 회 는 연합 색인 user 만 사용 합 니 다.id 필드,따라서 효율 이 높 지 않 습 니 다.
다음은 다음 예 를 살 펴 보 겠 습 니 다.
mysql> EXPLAIN SELECT * FROM order_info WHERE user_id = 1 AND product_name = 'p1' \G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: order_info
partitions: NULL
type: ref
possible_keys: user_product_detail_index
key: user_product_detail_index
key_len: 161
ref: const,const
rows: 2
filtered: 100.00
Extra: Using index
1 row in set, 1 warning (0.00 sec)
이번 조회 에서 우 리 는 범위 조회,key 를 사용 하지 않 았 습 니 다.len 의 값 은 161 입 니 다.왜 죠?저희 조회 조건 때문에 WHERE userid = 1 AND product_name='p1'에 서 는 연합 색인 의 앞 두 필드 만 사 용 했 기 때문에 keyLen(userid) + keyLen(product_name) = 9 + 50 * 3 + 2 = 161rows
rows 도 중요 한 필드 입 니 다.MySQL 조회 최적화 기 는 통계 정보 에 따라 SQL 이 결과 집합 을 찾 으 려 면 검색 하여 읽 어야 할 데이터 줄 수 를 찾 아야 합 니 다.
이 값 은 SQL 의 효율 이 좋 고 나 쁨 을 직관 적 으로 나타 내 며 원칙적으로 rows 가 적 을 수록 좋다.
Extra
EXplain 의 많은 추가 정 보 는 Extra 필드 에 표 시 됩 니 다.흔히 볼 수 있 는 것 은 다음 과 같은 몇 가지 내용 이 있 습 니 다.
예 를 들 어 다음 의 예:
mysql> EXPLAIN SELECT * FROM order_info ORDER BY product_name \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: order_info
partitions: NULL
type: index
possible_keys: NULL
key: user_product_detail_index
key_len: 253
ref: NULL
rows: 9
filtered: 100.00
Extra: Using index; Using filesort
1 row in set, 1 warning (0.00 sec)
저희 색인 은 요.
KEY `user_product_detail_index` (`user_id`, `product_name`, `productor`)
하지만 위의 조회 에 서 는 produtname 으로 정렬 하기 때문에 색인 을 사용 하여 최적화 할 수 없 기 때문에 Using filesort 가 생 길 수 있 습 니 다.만약 우리 가 정렬 근 거 를 ORDER BY user 로 바꾼다 면id, product_name,그러면 Using filesort 가 나타 나 지 않 습 니 다.예 를 들 어:
mysql> EXPLAIN SELECT * FROM order_info ORDER BY user_id, product_name \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: order_info
partitions: NULL
type: index
possible_keys: NULL
key: user_product_detail_index
key_len: 253
ref: NULL
rows: 9
filtered: 100.00
Extra: Using index
1 row in set, 1 warning (0.00 sec)
총결산
이상 은 이 글 의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가 치 를 가지 기 를 바 랍 니 다.여러분 의 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
MySQL에서 JSON 인덱싱 - aarondfrancis사람들은 종종 MySQL로 JSON을 인덱싱할 수 없다고 말하지만 완전히 정확하지는 않습니다. MySQL로 JSON 열을 인덱싱하는 것은 완전히 가능합니다! 사람들은 종종 MySQL로 JSON을 인덱싱할 수 없다고 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.