MySQL - Mysql 최적화(공식 문서에서), 인덱스 최적화 시리즈)

공식 홈페이지 문서

MySQL :: MySQL 5.7 참조 ​​설명서 :: 8.3 최적화 및 인덱스

Mysql 최적화(공식 문서에서) - 여덟 번째(인덱스 최적화 시리즈)

목차

최적화 및 색인

인덱스를 올바르게 생성하면 쿼리 속도가 빨라지는 경우가 많지만 불필요한 인덱스는 공간을 낭비하고 삽입, 업데이트 및 삭제의 오버헤드를 증가시키는 경우가 많습니다. 이러한 작업은 인덱스를 동시에 업데이트해야 하기 때문입니다.

그러나 지수는 만병통치약이 아니며 다음 시나리오에서는 지수가 그다지 유용하지 않습니다.

  • 작은 테이블 또는 큰 테이블이지만 모든 행을 요청해야 합니다.
  • 요청에 테이블에 있는 대부분의 행이 필요한 경우 연속 읽기가 디스크 탐색 시간을 줄이기 때문에 종종 연속 읽기가 인덱싱보다 더 효율적입니다.

1 외래 키 최적화

테이블에서 여러 열을 자주 읽는 경우 액세스가 가장 적은 열을 작은 테이블로 분리한 다음 외래 키를 사용하여 기본 테이블과 연결하여 최대한 많은 데이터를 읽을 수 있도록 디스크 I/O 읽기를 줄입니다. 그리고 씁니다.

2열 인덱스

  • 인덱스 접두사

    Mysql은 다음 예제와 같이 일부 필드의 일부만 인덱스로 사용할 수 있도록 허용합니다. 여기에는 all TEXT및 필드가 포함됩니다.BLOB

    CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
    

    유형 필드 의 경우 CHAR, VARCHAR, TEXT길이는 문자 수를 의미 하지만 필드와 같이 문자열이 아닌 필드의 경우 BINARY, VARBINARY, BLOB길이는 바이트 수를 의미합니다 .

  • 전체 텍스트 인덱스

    이 인덱스는 CHARVARCHAR 및  TEXT 열에 적용 가능하며 전체 텍스트 인덱스는 접두사를 지원하지 않으며 전체 열 인덱스만 지원합니다. 전체 텍스트 인덱싱은 쿼리가 다음 특성을 충족할 때 유용합니다.

    • FULLTEXT쿼리 문 값에는 document ID다음 중 하나가 필요합니다 search rank(grading??).
    • FULLTEXT질의문은 질의한 결과를 내림차순으로 정렬하며 LIMIT문 선택 top N항목이 있는데, 이때 최적화를 사용하기 위해서는 질의문이 컬럼이 없고 컬럼이 하나만 있는지 WHERE확인 해야 한다.ORDER BY
    • FULLTEXT쿼리는 COUNT(*)결과만 가져오고 문장은 없고 필터링이 WHERE필요하면 로 작성 하고 비교연산자 는 없습니다 .WHEREWHEREWHERE MATCH(TEXT) AGAINST('other_text')> 0
  • MEMORY 스토리지 엔진의 인덱스

    메모리 내 스토리지 엔진의 경우 HASH인덱스가 기본적으로 사용되지만 인덱스도 지원됩니다 BTREE.

3열 인덱스 && 다중 열 인덱스

Mysql은 단일 열을 인덱스로 지원하며 여러 열을 인덱스로 사용할 수도 있습니다.여러 열을 사용할 때 가장 왼쪽(인덱스의 가장 왼쪽 접두사) 열을 사용하여 쿼리하고 인덱스를 사용할 수 있습니다. 예를 들어 다음과 같이 색인을 사용할 수 있습니다.

테이블에 다음 인덱스가 포함되어 있다고 가정합니다.

 INDEX name (last_name,first_name)

이름 인덱스는 다음 쿼리 문에 사용할 수 있습니다.

SELECT * FROM test WHERE last_name='Jones';

SELECT * FROM test
  WHERE last_name='Jones'
  AND (first_name='John' OR first_name='Jon');
  
SELECT * FROM test
  WHERE last_name='Jones'
  AND first_name >='M' AND first_name < 'N';

다음 문은 쿼리에 가장 왼쪽 열을 사용하지 않기 때문에 인덱스를 사용할 수 없습니다.

SELECT * FROM test WHERE first_name='John';

SELECT * FROM test
  WHERE last_name='Jones' OR first_name='John';

and 가 2개 있다고 가정하고 인덱스가 col1and 에 col2구축되어 있으면 인덱스를 직접 사용할 수 있지만 합계가 별도의 인덱스(즉, 다중 열 인덱스가 아님)인 경우 Mysql 은 다음을 사용하려고 합니다  col1. ( 섹션 8.2.1.3, "인덱스 병합 최적화"  참조  ) 기술 또는 두 인덱스 중 어느 인덱스가 가장 엄격한지 판단하는 조건은 사용할 인덱스를 결정하기 전에 가능한 한 많은 행을 제외할 수 있습니다.col2col1col2Index Merge optimization

4 B-트리와 해시 인덱스의 비교

  • B-Tree 인덱스 특성

    B-트리 인덱스는  =>>=<<= 또는  BETWEEN 연산자를 지원하고 LIKE연산자도 지원하지만 LIKE필드가 와일드카드로 시작하지 않도록 해야 합니다.

    만약 인덱스가 모든 것을 커버하지 못한다면 ANDMysql은 인덱스를 사용할 수 없게 된다. 예 AND를 들어 다음과 같습니다.

    ... WHERE index_part1=1 AND index_part2=2 AND other_column=3
    
        /* index = 1 OR index = 2 */
    ... WHERE index=1 OR A=10 AND index=2
    
        /* optimized like "index_part1='hello'" */
    ... WHERE index_part1='hello' AND index_part3=5
    
        /* Can use index on index1 but not on index2 or index3 */
    ... WHERE index1=1 AND index2=2 OR index1=3 AND index3=3;
    

    다음 문은 인덱스를 사용하지 않습니다.

        /* index_part1 is not used */
    ... WHERE index_part2=1 AND index_part3=2
    
        /*  Index is not used in both parts of the WHERE clause  */
    ... WHERE index=1 OR A=10
    
        /* No index spans all rows  */
    ... WHERE index_part1=1 OR index_part2=10
    

    (잘 이해가 안 되시죠?)

    알아야 할 사항은 다음과 같습니다.

    Mysql은 항상 인덱스를 사용하도록 선택하지 않습니다.때때로 많은 수의 행을 읽어야 할 때 인덱스 사용의 효율성은 인덱스의 효율성보다 낮을 수 있습니다 table scan. 지속적인 읽기로 인해 디스크 table scanI/O를 보다 효율적으로 사용할 수 있습니다.

  • 해시 인덱스 특성

    Hash트리 인덱스 와 비교할 때 B인덱스에는 다음과 같은 차이점이 있을 수 있습니다.

    • Hash인덱스는 범위 쿼리가 아닌 =OR 연산자 에만 사용할 수 있습니다.<=>
    • 옵티마이저는 색인을 사용하여 작업 Hash속도를 높일 수 없습니다.ORDER BY
    • Mysql두 줄 사이에 value몇 줄( BETWEEN문) 이 있는지 평가할 수 없습니다.
    • 전체 인덱스 만 제대로 작동합니다. 그렇지 않으면 BTREE사용하십시오.leftmost prefix key

5 인덱스 확장 사용

InnoDB는 다음 표와 같이 내부적으로 수행되며 사용자가 인식할 수 없는 새 인덱스로 보조 인덱스에 기본 키를 자동으로 추가합니다.

CREATE TABLE t1 (
  i1 INT NOT NULL DEFAULT 0,
  i2 INT NOT NULL DEFAULT 0,
  d DATE DEFAULT NULL,
  PRIMARY KEY (i1, i2),
  INDEX k_d (d)
) ENGINE = InnoDB;

이때 인덱스 k_d에 대한 내부 실제 구현 방법은 다음과 같습니다.  (d, i1, i2)즉, k_d 뒤에 기본 키(i1, i2)가 자동으로 추가되어 새로운 보조 인덱스가 형성됩니다.

이 최적화 방법 은 인덱스 액세스 시나리오 에서 사용할 수 있습니다 refrangeindex_mergeLoose Index ScanjoinsortMIN()/MAX()。

예를 들어 다음 진술:

SELECT COUNT(*) FROM t1 WHERE i1 = 3 AND d = '2000-01-01'

이때 내부적으로 인덱스를 i1추가 할 것이기 때문에 이 문에서는 이러한 인덱스( 인덱스의 가장 왼쪽 접두사 )를 k_d사용할 수 있으며 , 더 많은 열을 사용하므로 스캔할 행의 수가 크게 줄어듭니다.(d, i1)(d, i1)(d, i1, i2)

6 보이지 않는 인덱스

이러한 종류의 인덱스는 실제로 존재하는 인덱스를 말하지만 옵티마이저에서는 사용하지 않고 non 으로만 설정할 수 있으며 primary key다른 종류의 인덱스는 로 설정할 수 있습니다 INVISIBLE.

예를 들면 다음과 같습니다.

CREATE TABLE t1 (
  i INT,
  j INT,
  k INT,
  INDEX i_idx (i) INVISIBLE
) ENGINE = InnoDB;
CREATE INDEX j_idx ON t1 (j) INVISIBLE;
ALTER TABLE t1 ADD INDEX k_idx (k) INVISIBLE;

이러한 종류의 인덱스의 일반적인 목적은 인덱스 제거가 성능에 미치는 영향을 테스트하는 것입니다. 이러한 종류의 인덱스는 실제로 제거되지는 않지만 옵티마이저는 더 이상 인덱스를 고려하지 않으므로 테이블에 큰 영향을 미치지 않습니다.

인덱스가 유효하지만 Invisible이 인덱스는 일반 인덱스와 동일한 완전한 기능을 가지고 있습니다.즉, 추가, 삭제 및 수정 시 Mysql도 업데이트됩니다.마찬가지로 매우 Invisible Index테이블에 생성된 경우 Invisible Index일반 인덱스와 동일합니다. , 비용도 매우 큽니다.

7 내림차순 인덱스

Mysql은 내림차순 인덱스를 지원하는데, 이전 버전과 달리 인덱스 정의의 DESC는 더 이상 무시되지 않고 인덱스의 내부 저장 방식도 내림차순으로 채택되는데, 이전에는 Mysql이 인덱스를 역순으로 스캔하는 방식을 사용했다. 현재 내림차순의 효율성은 이전보다 훨씬 높습니다.

내림차순 인덱스는 주로 다음 시나리오에 사용됩니다.

  • 내림차순 인덱스는 InnoDB 엔진만 지원하며 다음과 같은 제한이 있습니다.
    • 보조 인덱스에 내림차순 키가 있거나 기본 키에 내림차순 키가 있는 경우 Mysql은 버퍼링 수정을 지원할 수 없습니다.
    • InnoDB의 SQL 파서는 내림차순 인덱스를 사용하지 않습니다.전체 텍스트 쿼리의 경우 이는 이미 인덱싱된 테이블의 열을 FTS_DOC_ID 내림차순 인덱스로 정의할 수 없음을 의미합니다.
  • 내림차순 키가 있는 인덱스는 특히 GROUP BY 없이 집계 함수를 포함하는 명령문의 경우 MIN/MAX로 최적화할 수 없습니다.
  • 내림차순 인덱스는 HASH 인덱스가 아닌 BTREE만 지원하며 내림차순 인덱스는 FULLTEXT 또는 SPATIAL 인덱스를 지원할 수 없습니다.

Supongo que te gusta

Origin blog.csdn.net/MinggeQingchun/article/details/129933249
Recomendado
Clasificación