MySQL 성능 최적화 신기 Explain 의 기본 사용 분석

16984 단어 mysqlexplain성능
간단 한 소개
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)
각 열의 의 미 는 다음 과 같다.
  • id:SELECT 에서 조회 한 식별 자 입 니 다.모든 SELECT 는 하나의 유일한 식별 자 를 자동 으로 분배 합 니 다.
  • select_type:SELECT 조회 유형.
  • table:어느 시계
  • 를 조 회 했 습 니까?
  • partitions:일치 하 는 파 티 션
  • type:join type
  • possible_keys:이번 검색 에서 선택 할 수 있 는 색인
  • key:이번 검색 에서 정확하게 사 용 된 색인 입 니 다.
  • ref:키 와 함께 사용 되 는 필드 나 상수
  • rows:이 조회 가 모두 몇 줄 을 스 캔 했 는 지 보 여 줍 니 다.이것 은 추정 값 입 니 다.
  • filter:이 조회 조건 에서 걸 러 낸 데이터 의 백분율
  • 을 표시 합 니 다.
  • extra:추가 정보
  • 다음은 비교적 중요 한 몇 개의 필드 를 중점적으로 살 펴 보 자.
    select_type
  • select_type 은 검색 의 유형 을 표시 합 니 다.자주 사용 하 는 값 은 다음 과 같 습 니 다.
  • SIMPLE 는 이 조회 에 UNION 조회 나 하위 조회 가 포함 되 지 않 음 을 나타 낸다
  • PRIMARY 는 이 조회 가 가장 바깥쪽 조회 임 을 나타 낸다
  • UNION 은 이 조회 가 UNION 의 두 번 째 또는 그 다음 조회
  • 라 고 밝 혔 다.
  • DEPENDENT UNION,UNION 의 두 번 째 또는 뒤의 조회 문 구 는 바깥 조회
  • 에 달 려 있다.
  • UNION RESULT,UNION 결과
  • SUBQUERY,하위 조회 중 첫 번 째 SELECT
  • DEPENDENT SUBQUERY:하위 조회 중의 첫 번 째 SELECT 는 외부 조회 에 달 려 있다.즉,하위 조 회 는 외부 조회 결과 에 의존한다.
  • 가장 흔히 볼 수 있 는 조회 유형 은 SIMPLE 일 것 입 니 다.예 를 들 어 우리 의 조회 에 하위 조회 도 없고 UNION 조회 도 없 을 때 보통 SIMPLE 유형 입 니 다.예 를 들 어:
    
    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 에서 자주 사용 하 는 값 은:
  • 시스템:표 에 데이터 가 하나 밖 에 없습니다.이 유형 은 특수 한 const 형식 입 니 다.
  • const:메 인 키 나 유일한 색인 에 대한 등가 조회 스 캔 은 최대 한 줄 의 데이터 만 되 돌려 줍 니 다.const 조회 속 도 는 매우 빠 릅 니 다.한 번 만 읽 으 면 되 기 때 문 입 니 다.
    예 를 들 어 아래 의 이 조 회 는 메 인 키 색인 을 사 용 했 기 때문에 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)
  • eq_ref:이 유형 은 보통 여러 표 의 join 조회 에 나타 나 는데 앞 표 의 모든 결과 에 대해 뒷 표 의 한 줄 결과 만 일치 할 수 있 음 을 나타 낸다.또한 조회 의 비교 작업 은 보통=이 고 조회 효율 이 비교적 높다.예 를 들 어
  • 
    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)
  • ref:이 유형 은 보통 여러 표 의 join 조회 에 나타 납 니 다.유일 하지 않 거나 메 인 키 가 아 닌 색인 이나 가장 왼쪽 접두사 규칙 색인 을 사용 한 조회 입 니 다.
  • 예 를 들 어 다음 예 에서 ref 형식의 조회 에 사 용 됩 니 다.
    
    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)
  • range:색인 범 위 를 조회 하고 색인 필드 범 위 를 통 해 표 의 일부 데이터 기록 을 가 져 옵 니 다.이 유형 은 보통=,<>,>,>,=,<,<=,IS NULL,<=>,BETWEEN,IN()작업 에 나타 납 니 다.
  • type 이 range 일 때 EXPLAIN 이 출력 한 ref 필드 는 NULL 이 고 key 입 니 다.len 필드 는 이번 검색 에서 사용 한 색인 중 가장 긴 것 입 니 다.
    예 를 들 어 아래 의 예 는 하나의 범위 조회 이다.
    
    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)
  • index:전체 색인 스 캔(full index scan)을 표시 합 니 다.ALL 형식 과 유사 합 니 다.ALL 형식 은 전체 표 스 캔 일 뿐 index 형식 은 모든 색인 만 스 캔 하고 데 이 터 를 스 캔 하지 않 습 니 다.
  • index 형식 은 보통 다음 과 같 습 니 다.검색 할 데 이 터 는 색인 트 리 에서 직접 얻 을 수 있 습 니 다.데 이 터 를 검색 하지 않 아 도 됩 니 다.이 경우 Extra 필드 는 Using index 를 표시 합 니 다.
    예 를 들 면:
    
    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 입 니 다.
  • ALL:전체 표 스 캔 을 표시 합 니 다.이 유형의 조 회 는 성능 이 가장 나 쁜 조회 중 하나 입 니 다.일반적으로 우리 의 조 회 는 ALL 유형의 조회 가 나타 나 서 는 안 됩 니 다.이러한 조 회 는 데이터 양 이 많은 상황 에서 데이터 베이스 의 성능 에 큰 재난 입 니 다.예 를 들 어 하나의 조 회 는 ALL 유형 조회 입 니 다.일반적으로 해당 필드 에 색인 을 추가 하여 피 할 수 있 습 니 다.
  • 다음은 전체 표 스 캔 의 예 입 니 다.전체 표 스 캔 시 possiblekeys 와 key 필드 는 모두 NULL 로 색인 을 사용 하지 않 았 고 rows 가 매우 커서 전체 조회 효율 이 매우 낮 습 니 다.
    
    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 의 계산 규칙 은 다음 과 같다.
    문자열
  • char(n):n 바이트 길이
  • varchar(n):utf 8 인 코딩 이 라면 3 n+2 바이트 입 니 다.utf8mb 4 인 코딩 이 라면 4 n+2 바이트 입 니 다.
  • 수치 형식:
  • TINYINT:1 바이트
  • SMALLIT:2 바이트
  • MEDIUINT:3 바이트
  • INT:4 바이트
  • BIGINT:8 바이트
  • 시간 유형
  • 날짜:3 바이트
  • TIMESTAMP:4 바이트
  • 날짜:8 바이트
  • 필드 속성:NULL 속성 이 바이트 하 나 를 차지 합 니 다.필드 가 NOT NULL 이면 이 속성 이 없습니다.
    우 리 는 간단 한 밤 두 개 를 들 었 다.
    
    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 = 161
    rows
    rows 도 중요 한 필드 입 니 다.MySQL 조회 최적화 기 는 통계 정보 에 따라 SQL 이 결과 집합 을 찾 으 려 면 검색 하여 읽 어야 할 데이터 줄 수 를 찾 아야 합 니 다.
    이 값 은 SQL 의 효율 이 좋 고 나 쁨 을 직관 적 으로 나타 내 며 원칙적으로 rows 가 적 을 수록 좋다.
    Extra
    EXplain 의 많은 추가 정 보 는 Extra 필드 에 표 시 됩 니 다.흔히 볼 수 있 는 것 은 다음 과 같은 몇 가지 내용 이 있 습 니 다.
  • Using filesort
  • Extra 에 Using filesort 가 있 을 때 MySQL 은 추가 정렬 작업 이 필요 하 며 색인 순 서 를 통 해 정렬 효 과 를 얻 을 수 없습니다.일반적으로 Using filesort 가 있 으 므 로 최적화 제거 하 는 것 을 권장 합 니 다.이러한 조회 CPU 자원 소모 가 크기 때 문 입 니 다.
    예 를 들 어 다음 의 예:
    
    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)
  • Using index
  • "덮어 쓰기 색인 검색"은 색인 트 리 에서 필요 한 데 이 터 를 찾 을 수 있 음 을 나타 내 며,표 데이터 파일 을 검색 하지 않 아 도 성능 이 좋다 는 것 을 나타 낸다.
  • Using temporary
  • 조 회 는 임시 표를 사용 하 는데 보통 정렬,그룹 과 다 중 표 join 의 경우 조회 효율 이 높 지 않 으 므 로 최적화 하 는 것 을 권장 합 니 다.
    총결산
    이상 은 이 글 의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가 치 를 가지 기 를 바 랍 니 다.여러분 의 저희 에 대한 지지 에 감 사 드 립 니 다.

    좋은 웹페이지 즐겨찾기