Mysql 색인 선택 및 최적화 상세 설명

인덱스 모델
해시 시계
  • 등가 조회 만 있 는 장면 에 적용 되 며,Memory 엔진 기본 색인
  • InnoDB 는 해시 색인 에 적응 하 는 것 을 지원 합 니 다.관여 할 수 없습니다.엔진 이 자체 적 으로 생 성 여 부 를 결정 합 니 다.
  • 질서 있 는 배열:등가 조회 와 범위 조회 장면 에서 의 성능 이 매우 우수 하지만 데 이 터 를 삽입 하고 삭제 하려 면 데이터 이동 을 해 야 하고 원가 가 너무 높다.따라서 정적 저장 엔진 에 만 적 용 됩 니 다.
    이 진 밸 런 스 트 리:각 노드 의 왼쪽 아들 은 아버지 노드 보다 작고 아버지 노드 는 오른쪽 아들 보다 작 으 며 시간 복잡 도 는 O(log(N)이다.
    다 중 균형 트 리:색인 은 메모리 뿐만 아니 라 디스크 에 도 적 혀 있 습 니 다.조회 가 가능 한 한 디스크 를 적 게 읽 도록 하기 위해 서 는 조회 과정 이 가능 한 한 적은 데이터 블록 에 접근 하도록 해 야 한다.따라서'N 포크'트 리 를 사용 해 야 한다.
    B+Tree
    B-Tree 와 B+Tree
    B-Tree

    B+Tree

    이 노 DB 는 B+트 리 인덱스 모델 을 사용 했다.만약 에 우리 가 메 인 키 가 ID 로 열 거 된 표 가 있다 고 가정 하면 표 에 필드 k 가 있 고 k 에 색인 이 있 습 니 다.다음 과 같 습 니 다.
  • 메 인 키 색인:클 러 스 터 색인 이 라 고도 부 르 는데 잎 노드 에 저 장 된 것 은 전체 줄 데이터
  • 입 니 다.
  • 비 메 인 키 색인:2 급 색인 이 라 고도 불 리 며 잎 노드 내용 은 메 인 키 의 값 입 니 다.
  • 주의 사항
  • 색인 은 데이터 페이지 의 질서 있 는 저장 을 바탕 으로 데이터 페이지 의 분열(페이지 저장 공간 부족)과 합병(데이터 삭제 로 인해 페이지 이 용 률 이 낮 음)
  • 이 발생 할 수 있 습 니 다.
  • 데이터 의 무질서 한 삽입 은 데이터 의 이동,심지어 데이터 페이지 의 분열
  • 을 초래 할 수 있다.
  • 메 인 키 의 길이 가 작 을 수록 일반 색인 의 잎 노드 가 작 아 지고 일반 색인 이 차지 하 는 공간 도 작 아진 다
  • 색인 필드 가 작 을 수록 단층 저장 가능 한 데 이 터 량 이 많 을 수록 디스크 IO 를 줄 일 수 있 습 니 다.
  • 
    //        16K、    1K、     6  、    bigint  (8  )
    
    //     
    K = 16*1024/(8+6) =1170
    
    //          
    N = 16/1 = 16
    
    //   B+   
    V = K*K*N = 21902400
    
    
    MyISAM 도 B+Tree 색인 을 사용 합 니 다.메 인 키 와 비 메 인 키 색인 을 구분 하지 않 고 모두 비 클 러 스 터 색인 이 며,잎 노드 는 데이터 파일 의 지침 을 저장 합 니 다.
    색인 선택
    최적화 기 가 색인 을 선택 하 는 목적 은 가장 좋 은 실행 방안 을 찾 고 가장 작은 대가 로 문 구 를 실행 하 는 것 이다.데이터베이스 에서 스 캔 줄 수 는 집행 대가 에 영향 을 주 는 요소 중 하나 이다.스 캔 한 줄 수가 적 을 수록 디스크 데이터 에 접근 하 는 횟수 가 적 고 CPU 자원 이 적 다 는 뜻 입 니 다.
    물론 스 캔 줄 수 는 유일한 판단 기준 이 아니 며,최적화 기 는 임시 표 사용 여부,정렬 여부 등 을 결합 해 종합 적 으로 판단 한다.
    스캐닝 줄 수 는 어떻게 계산 합 니까?
    하나의 색인 에 서로 다른 값 이 많 을 수록 이 색인 의 구분 도 는 더욱 좋다.색인 에 있 는 서로 다른 값 의 개 수 를'기수'(cardinality)라 고 합 니 다.
    
    --         
    mysql> show index from test;
    +-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
    +-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | test |   0 | PRIMARY |   1 | id   | A   |  100256 | NULL  | NULL |  | BTREE  |   |    |
    | test |   1 | index_a |   1 | a   | A   |  98199 | NULL  | NULL | YES | BTREE  |   |    |
    +-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    
    성능 측면 에서 볼 때 InnoDB 는 샘플링 통 계 를 사용 하여 기본적으로 N 개의 데이터 페이지 를 선택 하고 이 페이지 의 서로 다른 값 을 통계 하여 평균 값 을 얻 은 다음 에 이 색인 의 페이지 수 를 곱 하면 이 색인 의 기 수 를 얻 을 수 있다.따라서 상기 두 색인 에 표 시 된 기 수 는 같 지 않다.
    데이터 시트 는 지속 적 으로 업데이트 되 고 색인 통계 정보 도 고정 되 지 않 습 니 다.따라서 변 경 된 데이터 줄 수가 1/M 을 넘 을 때(innodbstats_persistent=on 시 기본 10,반대로 16)색인 통 계 를 다시 만 드 는 것 이 자동 으로 실 행 됩 니 다.
    
    mysql> show variables like '%innodb_stats_persistent%';
    +--------------------------------------+-------------+
    | Variable_name      | Value  |
    +--------------------------------------+-------------+
    --             ,         10%               
    | innodb_stats_auto_recalc    | ON   |
    --                         
    | innodb_stats_include_delete_marked | OFF   |
    --  null      ,      nulls_equal ,  NULL       
    | innodb_stats_method     | nulls_equal | 
    --                 
    | innodb_stats_on_metadata    | OFF   |
    --            
    | innodb_stats_persistent    | ON   |
    -- innodb_stats_persistent=on,              
    | innodb_stats_persistent_sample_pages | 20   |
    --      ,   innodb_stats_transient_sample_pages  
    | innodb_stats_sample_pages   | 8   |
    --     page 
    | innodb_stats_transient_sample_pages | 8   |
    +--------------------------------------+-------------+
    
  • 표본 추출 로 인해 통계 기수 가 정확 하지 않 은 것 을 제외 하고 MVCC 도 기수 통계 가 정확 하지 않 을 수 있다.예 를 들 어 트 랜 잭 션 A 는 먼저 트 랜 잭 션 B 가 열 리 고 제출 되 지 않 았 습 니 다.트 랜 잭 션 B 는 일부 데 이 터 를 삭 제 했 습 니 다.중복 읽 기 가능 한 트 랜 잭 션 A 는 삭 제 된 데 이 터 를 조회 할 수 있 습 니 다.이 부분 데 이 터 는 현재 적어도 두 가지 버 전이 있 고 삭 제 된 데이터 로 표 시 됩 니 다.
  • 메 인 키 는 표 의 줄 수 에 따라 직접 평가 합 니 다.표 의 줄 수,최적화 기 는 show table status like't'의 값 을 직접 사용 합 니 다
  • 수 동 트리거 색인 통계:
  • 
    --         
    mysql> analyze table t;
    
    정렬 이 색인 선택 에 미 치 는 영향
    
    --    
    mysql> CREATE TABLE `t` (
    `id` int(11) NOT NULL,
    `a` int(11) DEFAULT NULL,
    `b` int(11) DEFAULT NULL,
    PRIMARY KEY (`id`),
    KEY `a` (`a`),
    KEY `b` (`b`)
    ) ENGINE=InnoDB;
    
    --           
    mysql> delimiter ;
    CREATE PROCEDURE idata ()
    BEGIN
    
    DECLARE i INT ;
    SET i = 1 ;
    WHILE (i <= 100000) DO
     INSERT INTO t
    VALUES
     (i, i, i) ;
    SET i = i + 1 ;
    END
    WHILE ;
    END;
    delimiter ;
    
    --       ,      
    mysql> CALL idata ();
    
    --       ,     a    
    mysql> explain select * from t where a between 10000 and 20000;
    +----+-------------+-------+-------+---------------+-----+---------+------+-------+-----------------------+
    | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra         |
    +----+-------------+-------+-------+---------------+-----+---------+------+-------+-----------------------+
    | 1 | SIMPLE   | t   | range | a       | a  | 5    | NULL | 10000 | Using index condition |
    +----+-------------+-------+-------+---------------+-----+---------+------+-------+-----------------------+
    
    --         b  ,    b         ,       ,         ,        b,      
    mysql> explain select * from t where (a between 1 and 1000) and (b between 50000 and 100000) order by b limit 1;
    +----+-------------+-------+-------+---------------+-----+---------+------+-------+------------------------------------+
    | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra               |
    +----+-------------+-------+-------+---------------+-----+---------+------+-------+------------------------------------+
    | 1 | SIMPLE   | t   | range | a,b      | b  | 5    | NULL | 50128 | Using index condition; Using where |
    +----+-------------+-------+-------+---------------+-----+---------+------+-------+------------------------------------+
    
    --   1:  force index     a,          ,     (   ,             )
    mysql> explain select * from t force index(a) where (a between 1 and 1000) and (b between 50000 and 100000) order by b limit 1;
    +----+-------------+-------+-------+---------------+-----+---------+------+------+----------------------------------------------------+
    | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra                       |
    +----+-------------+-------+-------+---------------+-----+---------+------+------+----------------------------------------------------+
    | 1 | SIMPLE   | t   | range | a       | a  | 5    | NULL | 999 | Using index condition; Using where; Using filesort |
    +----+-------------+-------+-------+---------------+-----+---------+------+------+----------------------------------------------------+
    
    --   2:   MySQL          , b,a  ,       a     
    mysql> explain select * from t where (a between 1 and 1000) and (b between 50000 and 100000) order by b,a limit 1;
    +----+-------------+-------+-------+---------------+-----+---------+------+------+----------------------------------------------------+
    | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra                       |
    +----+-------------+-------+-------+---------------+-----+---------+------+------+----------------------------------------------------+
    | 1 | SIMPLE   | t   | range | a,b      | a  | 5    | NULL | 999 | Using index condition; Using where; Using filesort |
    +----+-------------+-------+-------+---------------+-----+---------+------+------+----------------------------------------------------+
    
    --   3:     ,              ,          ,        
    ALTER TABLE `t`
    DROP INDEX `a`,
    DROP INDEX `b`,
    ADD INDEX `ab` (`a`,`b`) ;
    
    
    색인 최적화
    색인 선택성
    색인 선택성
    
    --  t   xxx      
    select count(distinct xxx)/count(id) from t;
    
    색인 의 선택성 은 중복 되 지 않 는 색인 값(기수)과 표 기록 수의 비례 를 가리킨다.선택성 은 색인 선별 능력 의 한 지표 로 색인 의 수치 범 위 는 0~1 이 며 선택성 이 클 수록 색인 가치 도 커진다.
    일반 색인 조 회 를 사용 할 때 일반 색인 을 불 러 오고 일반 색인 을 통 해 실제 줄 의 홈 키 를 조회 한 다음 에 홈 키 를 사용 하여 색인 을 모 아 해당 줄 을 조회 하여 모든 줄 을 순환 적 으로 조회 합 니 다.전체 색인 을 직접 검색 하면 일반 색인 과 집합 색인 을 오 가 며 전환 할 필요 가 없 으 며,두 가지 작업 의 총 비용 보다 전체 표를 스 캔 하 는 효율 이 높 을 수 있 습 니 다.
    실제 업무 에 서 는 업무 상황 을 봐 야 한다.만약 에 데이터 분포 가 불 균형 하면 실제 조회 조건 은 데이터 가 비교적 적은 부분 을 조회 하고 색인 선택 이 비교적 낮은 열 에 색인 을 추가 하면 효과 도 좋 을 것 이다.
    겹 쳐 쓰기 인덱스
    덮어 쓰기 인덱스 는 트 리 의 검색 횟수 를 줄 이 고 검색 성능 을 현저히 향상 시 킬 수 있 기 때문에 덮어 쓰기 인덱스 를 사용 하 는 것 은 자주 사용 하 는 성능 최적화 수단 이다
    
    --      ID   ,  ID       k      ,            ,     
    select ID from T where k between 3 and 5
    
    --     V,        V,    k、v      
    select ID,V from T where k between 3 and 5
    
    
    맨 왼쪽 접두사 원칙+색인 아래 밀어 내기
    
    -- id、name、age  ,name、age       
    
    --         ,name、age    
    select * from T where name='xxx' and age=12
    
    -- Mysql    ,  name、age  ,,name、age    
    select * from T where age=12 and name='xxx'
    
    -- name           ,MySQL5.6        (index condition pushdown),           age=12      
    select * from T where name like 'xxx%' and age=12
    
    --          ,     
    select * from T where name like '%xxx%' and age=12
    
    --         ,name   
    select * from T where name='xxx'
    
    --          ,    
    select * from T where age=12
    
    
    연합 색인 생 성 원칙:
  • 순 서 를 조정 하면 색인 을 적 게 유지 할 수 있다 면 이 순 서 는 우선적으로 고려 해 야 하 는 경우 가 많다
  • 공간:우선 작은 필드 에 따로 색인 을 만 듭 니 다.예 를 들 어 name,age,(name,age)공동 색인 과(age)단일 필드 색인 을 만 들 수 있 습 니 다.
  • 접두사 인덱스
    
    mysql> create table SUser(
    ID bigint unsigned primary key,
    name varchar(64),  
    email varchar(64),
    ...
    )engine=innodb;
    
    --       
    mysql> select name from SUser where email='xxx';
    
    --   1:     ,               
    mysql> alter table SUser add index index1(email);
    
    --   2:    ,             
    mysql> alter table SUser add index index2(email(6));
    
    
    접두사 색인 은 공간 을 절약 할 수 있 지만 접두사 길이 의 정 의 를 주의해 야 합 니 다.공간 을 절약 하 는 동시에 조회 원 가 를 너무 많이 증가 해 서 는 안 됩 니 다.즉,리 턴 검증 횟수 를 줄 이 는 것 입 니 다.
    어떻게 적합 한 접두사 길 이 를 설정 합 니까?
    
    --                ,              
    select count(distinct left(email,n))/count(distinct email) from SUser;
    
    적당 한 접두사 길이 가 길 면?
    예 를 들 어 신분증 번호 가 구역 구분 요 구 를 만족 시 키 면 12 비트 이상 의 접두사 색인 이 필요 할 수 있 고 절약 하 는 공간 이 유한 하 며 조회 원 가 를 증가 하면 접두사 색인 을 사용 할 필요 가 없다.이때 우 리 는 다음 과 같은 방식 을 고려 할 수 있다.
    역순 저장 소
    
    --           
    mysql> select field_list from t where id_card = reverse('input_id_card_string');
    
    hash 필드 사용 하기
    
    --         ,          ,            
    mysql> alter table t add id_card_crc int unsigned, add index(id_card_crc);
    
    --      hash       ,          
    mysql> select field_list from t where id_card_crc=crc32('input_id_card_string') and id_card='input_id_card_string'
    
    
    상기 두 가지 방식 의 단점:
  • 범위 조회 지원 되 지 않 음
  • hash 필드 를 사용 하려 면 추가 로 공간 을 차지 해 야 합 니 다.필드
  • 가 추가 되 었 습 니 다.
  • 읽 기와 쓰기 시 추가 처리,reverse 또는 crc 32 등 이 필요 합 니 다.
  • 접두사 인덱스 가 덮어 쓰기 인덱스 에 미 치 는 영향 은?
    
    --                       
    select id,email from SUser where email='xxx';
    
    유일한 인덱스
    일반 색인 을 사용 하 는 것 을 권장 합 니 다.유일한 색인 은 change buffer 를 사용 할 수 없고 메모리 명중률 이 낮 습 니 다.
    인덱스 실효
  • 열 연산 을 하지 않 고 함수 의 사용 을 포함 하여 색인 값 의 질서 성 을 파괴 할 수 있 습 니 다
  • %x xx 식 조 회 를 피하 여 색인 을 무효 화 합 니 다
  • or 문 구 는 앞 뒤 에 색인 을 동시에 사용 하지 않 았 습 니 다.or 좌우 검색 필드 는 하나의 색인 만 있 을 때 이 색인 은 유효 하지 않 습 니 다
  • 조합 색인 ABC 문제,최 좌 접두사 원칙
  • 암시 적 유형 전환
  • 암시 적 문자 인 코딩 변환
  • 유 틸 리 티 는 색인,리 턴,정렬 원가 등 요소 의 영향 을 포기 하고 다른 색인 이나 모든 스 캔
  • 을 바 꿉 니 다.
    총결산
    Mysql 색인 선택 및 최적화 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 Mysql 색인 선택 최적화 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!

    좋은 웹페이지 즐겨찾기