"효율적인 인덱싱 기술: 인덱스 분류, MySQL 인덱스 사용, 가장 왼쪽 일치 원칙, 테이블 반환 쿼리, 테이블 반환 방지 방법, 인덱스 푸시다운 및 인덱스 생성 시 주의 사항"

색인

MySQL 인덱스의 분류

1. 일반 인덱스와 고유 인덱스


일반 인덱스(Ordinary index): MySQL의 기본 인덱스 유형으로, 인덱스를 정의하는 열에 중복된 값과 null 값을 삽입할 수 있다. 허용됩니다
.결합된 인덱스인 경우 열 값의 조합은 다음과 같아야 합니다. 고유
기본 키 인덱스는 Null 값을 허용하지 않는 특수한 고유 인덱스입니다.

2. 단일 컬럼 인덱스와 결합 인덱스

단일 컬럼 인덱스: 하나의 컬럼만 포함하는 인덱스, 테이블은 여러 개의 단일 컬럼 인덱스를 가질 수 있음
결합 인덱스: 테이블의 여러 필드 조합에 대해 생성된 인덱스
다중 단일 컬럼 인덱스 여러 개의 단일 컬럼 인덱스로 쿼리하는 경우 조건에 따라 최적화 프로그램은 최적의 인덱스 전략을 선택합니다. 하나의 인덱스만 사용할 수도 있고 여러 인덱스를 사용할 수도 있습니다! 그러나 단일 컬럼 인덱스를 여러 개 생성하면 하단에 B+ 인덱스 트리를 여러 개 구축하게 되어 디스크 공간을 차지하고 검색 효율성도 어느 정도 낭비되기 때문에 조건이 여러 개인 조인트 쿼리만 있는 경우 결합 쿼리를 구축하는 것이 가장 좋습니다. 색인!

3. 전문 색인

전체 텍스트 인덱스의 종류는 전체 텍스트(fulltext)이며, 인덱스가 정의된 열의
에 대한 전체 텍스트 검색을 지원하므로 이러한 인덱스 열에 중복된 값과 Null 값을 삽입할 수 있습니다.
텍스트 인덱스는 char, varchar 및 text 유형의 열에 생성될 수 있습니다.

4. 공간 색인

공간 인덱스는 공간 데이터 유형의 필드에 설정된 인덱스입니다
. MySQL에는 Geometry, Point, Linestring 및 Polygon의 네 가지 공간 데이터 유형이 있습니다.
MySQL은 Spatial 키워드를 사용하여 이를 확장하여 생성과 유사한 구문을 사용하여 공간을 생성할 수 있습니다. 일반 인덱스
공간 인덱스를 생성하는 데 사용되는 인덱스 열은 Null 값을 허용하지 않으며 MyISAM 테이블에서만 생성할 수 있습니다.

5. 접두사 색인

char, varchar 및 text 유형의 열에 인덱스를 생성할 때 인덱스 열의 길이를 지정할 수 있습니다.

MySQL 인덱스 사용

1. 일반 인덱스에 INDEX 추가

ALTER TABLE table_name ADD INDEX index_name ( column )

2. 기본 키 인덱스에 PRIMARY KEY를 추가합니다.

ALTER TABLE table_name ADD PRIMARY KEY ( column )

3. 고유 인덱스에 UNIQUE 추가

ALTER TABLE table_name ADD UNIQUE ( column )

4. 전체 텍스트 색인에 FULLTEXT 추가

ALTER TABLE table_name ADD FULLTEXT ( column )

5. 다중 열 색인 추가

ALTER TABLE table_name ADD INDEX index_name ( column1, column2, column3 )

6. 인덱스 삭제

table_name의 DROP 인덱스 index_name;``

7. 색인 보기

table_name의 인덱스 표시;

가장 왼쪽 일치 원칙

가장 왼쪽 우선순위, 가장 왼쪽부터 시작하는 연속 인덱스가 일치될 수 있습니다. 동시에 범위 쿼리(>, <, between, like)가 발생하면 일치가 중지됩니다.
모든 열을 일치시키는 경우:
학생 테이블:

CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `gid` int(11) NOT NULL,
  `cid` int(11) DEFAULT NULL,
  `uid` int(11) DEFAULT NULL,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uni_Gid_Cid_SId` (`gid`,`cid`,`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

결론: 쿼리 열 순서를 수정하고 동일한 결과를 찾습니다. 이는 MySQL이 최적화 프로그램을 통해 인덱스 순서를 자동으로 최적화하기 때문입니다.

#ALTER TABLE index user_index on user(name,sex,age)
#可以使用复合索引:索引中包含的最左侧字段,只是顺序不正确,在执行的时候可以动态调整为最前左缀,下列执行计划type为ref
select * from user where sex = ? and age = ? and name = ?
select * from user where age = ? and name = ?

#不可以使用复合索引:因为缺少左侧字段
select * from user where sex = ? and age = ? 
select * from user where age = ?
select * from user where sex = ? 
#当缺少左侧字段时,不使用*,使用具体需要的复合索引字段时 依旧会走索引 此时执行计划的type为index
select name,sex,age from user where sex = ? and age = ?

가장 왼쪽의 접미사 원리는 스킵 스캐닝을 통해 깨질 수 있다.이 지식을 간략하게 정리해보자.
이것은 8.0에서 최적화되었다
.MySQL 버전 8.0부터 인덱스 스킵 스캐닝 기능이 추가되기 시작했다.첫 번째 열의 고유 값 개수가 index가 작은 경우 where 조건에 첫 번째 열 인덱스가 없더라도 쿼리 시에는 조인트 인덱스를 사용할 수 있습니다. 예를 들어 우리가 사용하는 조인트 인덱스는 bcd인데 b에는 상대적으로 필드가 적습니다. 조인트 인덱스를 사용할 때 b를 사용하지 않지만 여전히 조인트 인덱스를 사용할 수 있습니다. MySQL 조인트 인덱스는 때때로 가장 왼쪽 접두사 일치 원칙을 따릅니다. , 때로는 그렇지 않습니다.

테이블 쿼리 반환

이는 InnoDB의 인덱스 구현으로 시작됩니다. InnoDB에는 두 가지 주요 인덱스 유형이 있습니다.

  • 클러스터형 인덱스
  • 보조 인덱스

InnoDB 클러스터형 인덱스와 일반 인덱스의 차이점:

InnoDB 클러스터형 인덱스 의 리프 노드에는 행 레코드가 저장 되므로 InnoDB에는 클러스터형 인덱스가 하나만 있어야 합니다.

  1. 테이블이 PK를 정의하는 경우 PK는 클러스터형 인덱스입니다 .
  2. 테이블이 PK를 정의하지 않는 경우 NULL이 아닌 첫 번째 고유 열은 클러스터형 인덱스입니다.
  3. 그렇지 않으면 InnoDB는 숨겨진 행 ID를 클러스터형 인덱스로 생성 하고
    InnoDB 일반 인덱스 의 리프 노드는 기본 키 값을 저장합니다.

클러스터형 인덱스와 일반 인덱스 데이터 구조는 모두 b+ 트리로 모든 데이터가 리프 노드에 저장되고 리프 노드 사이를 가리키는 포인터가 있는 것이 특징입니다.


예를 들어, t(id PK, name KEY, sex, flag) 테이블이 있을 수도 있습니다 .
id는 클러스터형 인덱스이고 name은 일반 인덱스입니다.
테이블에는 4개의 레코드가 있습니다.

1, shenjian, m, A
3, zhangsan, m, A
5, lisi, m, A
9, wangwu, f, B

클러스터형 인덱스와 일반 인덱스는 다음과 같습니다.
[그림]

일반 인덱스를 통해 데이터를 검색할 때 인덱스 외에 다른 컬럼 필드가 있으면 클러스터형 인덱스에서 검색이 수행됩니다.
select * from t where name='lisi'; # 该语句执行流程如下图
여기에 이미지 설명을 삽입하세요.

이는 기본 키 값을 먼저 찾은 다음 행 레코드를 찾는 이른바 테이블 반환 쿼리로 , 인덱스 트리를 스캔하는 것보다 성능이 낮습니다.

테이블 반환을 피하는 방법

포함 인덱스를 사용할 수 있습니다. 예를 들면 다음과 같습니다. 기존 사용자 테이블

CREATE TABLE `user`
(
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name`  int(11)     DEFAULT NULL,
  `sex`  char(3)     DEFAULT NULL,
  `address`  varchar(10) DEFAULT NULL,
  `hobby`  varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  KEY `i_name` (`name`)
) ENGINE = InnoDB;


name = 'zhangsan'인 사용자로부터 이름과 성별 선택 ID, 이름, 성별을 자주 쿼리해야 하는 시나리오가 있습니다
. 이 문은 비즈니스에서 자주 사용되며 사용자 테이블의 다른 필드의 사용률은 훨씬 낮습니다. 이 분야보다. 이 경우 이름 필드에 인덱스를 구축하면 단일 인덱스를 사용하는 대신 공동 인덱스(이름, 성별)를 사용합니다. 이 경우 이 쿼리문을 다시 실행하면 이 보조 인덱스(이름, 성별)를 기반으로 얻은 결과에는 필요한 쿼리 결과의 모든 필드에 대한 전체 데이터가 포함됩니다.

인덱스 푸시다운

이는 MySQL 5.6 이후에 제공되는 기능으로
b가 '3%'이고 c = 3인 table1에서 select *를 쿼리해야 한다고 가정합니다. 5.6 이전에는
인덱스 필드가 index(b,c)입니다.

  • 먼저 조인트 인덱스를 통해 3으로 시작하는 데이터를 질의하여 기본키를 얻는다. (위 그림의 하늘색 블록이 기본키이다.)
  • 그런 다음 기본 키를 사용하여 기본 키 인덱스로 이동하고 테이블로 돌아와 보조 인덱스를 쿼리하고 3으로 시작하는 몇 가지를 쿼리하고 테이블로 여러 번 반환합니다.

5.6 이후

  • 먼저 3으로 시작하는 데이터를 보조 인덱스를 통해 쿼리한 후, c = 3인 데이터를 찾아 필터링하고 기본 키를 가져옵니다.
  • 기본 키를 통해 테이블로 다시 쿼리합니다. 위에서는 모두 테이블로 다시 쿼리하지만 5.6 이전에는 2단계 캐시가 데이터 필터링에 완전히 사용되지 않았습니다.3으로 시작하는 데이터가 많으면 그런데 5.6 이후 에는
    후속 인덱스 필드를 쿼리에 사용하는 것에 대해 어떻게 말합니까?

인덱스 실패를 방지하는 방법

  • 결합 인덱스를 사용하는 경우 가장 왼쪽 일치 원칙을 따릅니다.
  • 계산, 함수, 유형 변환 등 인덱스 열에 대한 작업을 수행하지 마세요.
  • 커버링 인덱스를 사용해 보세요
  • 같지 않음(!= / <>) 조건, 와일드카드(예: %abc)로 시작하는 퍼지 쿼리 또는 인덱스 열에 대한 조인 조건을 사용하지 마십시오.
  • 문자열에 작은따옴표를 추가합니다(추가하지 않으면 인덱스 열의 암시적 변환이 발생하여 인덱스 오류가 발생할 수 있음).

각 열의 기능을 설명하세요.

여기에 이미지 설명을 삽입하세요.
여기에 이미지 설명을 삽입하세요.

(1) id : 테이블을 읽는 순서나 쿼리에서 select 절이 실행되는 순서를 반영한다.
① ID가 동일할 경우 위에서 아래로 실행순서가 됩니다.
② ID가 다른 경우 서브쿼리인 경우 ID 일련번호가 증가하며, ID 값이 클수록 우선순위가 높아 먼저 실행된다.
③ id가 동일할 경우 하나의 그룹으로 간주하여 위에서 아래로 순차적으로 실행될 수 있으며, 모든 그룹 중에서 id 값이 클수록 우선순위가 높아져 일찍 실행된다.

(2) select_type : select의 종류를 나타내며 주로 일반 질의, 결합 질의, 하위 질의 등 복잡한 질의를 구별하는데 사용된다.
① 단순: 단순 선택 쿼리로 서브 쿼리나 유니온을 포함하지 않습니다.
② 기본: 쿼리에 복잡한 하위 부분이 포함된 경우 가장 바깥쪽 쿼리가 기본으로 표시됩니다.
③ 하위 쿼리: 선택 또는 Where 목록의 하위 쿼리입니다.
④ 파생됨: from 목록에 포함된 하위 쿼리의 경우 MySQL은 이러한 하위 쿼리를 반복적으로 실행하고 결과를 임시 테이블에 저장합니다.
⑤ Union: Union 다음에 두 번째 Select가 나타나면 Union으로 표시되고, from 절의 하위 쿼리에 Union이 포함되면 Outer Select가 Derived로 표시된다.
⑥ Union 결과 : Union 이후에 설정된 결과입니다.

(3) table : 이 단계에서 접근한 데이터베이스의 테이블 이름을 표시합니다.(이 행의 데이터가 어떤 테이블을 참조하는지 표시합니다.) 때로는 실제 테이블 이름이 아니지만, 결과의 약어일 수도 있습니다. 여러 단계의 실행.

(4) 유형 : MySQL이 테이블에서 필요한 행을 찾는 방법을 나타내는 테이블에 대한 액세스 방법으로, "액세스 유형"이라고도 합니다. 일반적인 액세스 유형에는 ALL, index, range, ref, eq_ref, const, system 및 NULL(왼쪽에서 오른쪽으로, 성능이 최악에서 최고로)이 포함됩니다.
① ALL: 전체 테이블 스캔, MySQL은 전체 테이블을 탐색하여 일치하는 행을 찾습니다.
② index:: Full Index Scan, 인덱스와 ALL의 차이점은 인덱스 유형이 인덱스 트리만 순회한다는 점입니다.
③ 범위(Range): 인덱스 범위 스캔, 주어진 범위만 검색하는 행의 배치를 반환하고 인덱스를 사용하여 행을 선택합니다. 일반적으로 where 문에는 between, <, >, in 등과 같은 쿼리가 나타납니다. 이 범위 스캔 인덱스는 전체 인덱스를 스캔하지 않고 인덱스의 특정 지점에서 시작하여 다른 지점에서 끝나기만 하면 되기 때문에 전체 테이블 스캔보다 좋습니다.
④ ref: Non-unique index scan, 단일 값과 일치하는 모든 행을 반환합니다. 본질적으로 인덱스 액세스입니다. 단일 값과 일치하는 모든 행을 반환합니다. 그러나 조건에 맞는 여러 행을 찾을 수도 있으므로 반드시 수행해야 합니다. 검색과 스캔을 혼합해 보세요.
⑤ eq_ref: ref와 유사하게 사용되는 인덱스가 고유 인덱스라는 점이 차이점이며, 각 인덱스 키에 대해 테이블의 하나의 레코드만 일치하며 이는 기본 키 또는 고유 인덱스 스캔에서 흔히 발생합니다. 간단히 말하면 다중 테이블 연결에서는 기본 키(Primary Key) 또는 고유 키(Unique Key)가 연관 조건으로 사용됩니다.
⑥ const, system : MySQL이 쿼리의 특정 부분을 최적화하여 상수로 변환할 때 접근하기 위해 사용하는 타입이다. 쿼리 조건에서 상수를 사용하는 경우 인덱스를 통해 한 번만 찾을 수 있으며 기본 키나 고유 키를 사용하여 인덱스에 나타나는 경우가 많습니다. 시스템은 쿼리된 테이블에 행이 하나만 있을 때 사용되는 const 유형의 특수한 경우입니다.
⑦ NULL: MySQL은 최적화 과정에서 문장을 분해하고, 실행 중에 테이블이나 인덱스에 접근할 필요도 없다.예를 들어, 인덱스 컬럼에서 최소값을 선택하는 것은 별도의 인덱스 조회를 통해 완료될 수 있다.

(5) available_keys : MySQL이 테이블의 행을 찾기 위해 사용할 수 있는 인덱스를 나타내며, 쿼리에 포함된 필드에 인덱스가 있는 경우 해당 인덱스가 나열되지만 쿼리에서 반드시 사용되는 것은 아닙니다.

(6) key : MySQL이 실제로 사용하기로 결정한 인덱스를 표시하며, 인덱스를 선택하지 않으면 NULL로 표시된다. MySQL이 available_keys 열의 인덱스를 사용하거나 무시하도록 하려면 쿼리에 FORCE INDEX 또는 IGNORE INDEX를 사용하십시오. 쿼리에 포함 인덱스가 사용된 경우(선택 후 쿼리할 필드가 생성된 인덱스 필드와 정확히 동일함) 해당 인덱스는 키 목록에만 나타납니다.

(7) key_len : 인덱스에 사용된 바이트 수를 표시한다.

(8) ref : 위 표의 연결 매칭 조건, 즉 인덱스 컬럼의 값을 찾기 위해 어떤 컬럼이나 상수를 사용하는지를 나타낸다.

(9) : 테이블 통계 및 인덱스 선택을 기반으로 필요한 레코드를 찾기 위해 읽어야 할 행 수에 대한 MySQL의 추정치를 표시합니다.

(10) 추가 : 이 열에는 다른 열에 표시하기에 적합하지 않지만 실행 계획에 매우 중요한 추가 정보를 포함하여 MySQL이 쿼리를 해결하는 방법에 대한 지침과 설명이 포함되어 있습니다.
① where 사용: 테이블의 모든 정보를 읽지 않고 인덱스를 통해서만 필요한 데이터를 얻을 수 있는데, 이는 테이블의 요청된 모든 컬럼이 동일한 인덱스 부분에 있는 경우 발생하며, 이는 MySQL 서버가 해당 행을 검색한다는 의미입니다. 스토리지 엔진 이후에 필터링합니다.
② 임시 테이블 사용: 결과 집합을 저장하기 위해 MySQL이 임시 테이블을 사용해야 함을 나타냅니다. MySQL은 쿼리 결과를 정렬할 때 임시 테이블을 사용하는데, 이는 정렬(order by) 및 그룹 쿼리(group by)에서 흔히 발생합니다.
③ filesort 사용: Query에 연산별 정렬이 포함되어 있고 인덱스를 사용하여 정렬 작업을 완료할 수 없는 경우를 "파일 정렬"이라고 합니다. 인덱스 생성 시 데이터가 먼저 정렬됩니다. 일반적으로 filesort를 사용하는 이유는 다음과 같습니다. 인덱스 실패 원인으로 인해 주문한 후에는 최적화하는 것이 가장 좋습니다.
④ 조인 버퍼 사용: 연결 캐시를 사용함을 의미하며, 예를 들어 쿼리 시 다중 테이블 조인 개수가 매우 많기 때문에 설정 파일에서 조인 버퍼를 늘려준다. 이 값이 나타나는 경우 쿼리의 특정 상황에 따라 이를 개선하기 위해 인덱스를 추가해야 할 수도 있다는 점에 유의해야 합니다.
⑤ 인덱스 사용: 추가 검색 없이 인덱스 트리에 있는 정보만 사용하여 실제 행을 읽어 테이블의 컬럼 정보를 검색합니다. 테이블의 데이터 행에 대한 액세스를 방지하기 위해 해당 선택 작업에 ​​포함 인덱스가 사용되며 이는 매우 효율적입니다. Covering index: 선택한 데이터 열은 데이터 행을 읽지 않고 인덱스에서만 가져올 수 있으며, 생성된 인덱스 수(쿼리 열이 인덱스 수보다 작거나 같음) 및 순서와 일치합니다. 커버링 인덱스를 사용하려면 꼭 필요한 컬럼만 선택하도록 주의해야 하며, select*를 사용하지 말아야 하며, 동시에 모든 필드를 함께 인덱스하면 인덱스 파일이 너무 커지고 성능이 저하됩니다.
⑥ 인덱스 조건 사용: ICP 최적화가 수행되었음을 나타냅니다.

먼저 쿼리 타입의 타입 컬럼을 주의 깊게 살펴보자. all 키워드가 나온다면 테이블 전체를 스캔하고 인덱스를 사용하지 않는다는 뜻이다. 키 컬럼을 다시 살펴보자. 키 컬럼이 NULL이면 테이블 전체를 스캔한다는 뜻이다. 인덱스를 사용하지 않습니다. 그런 다음 행 열을 살펴보십시오. 이 열의 값이 클수록 값도 커집니다. 즉, 스캔해야 할 행이 많을수록 응답 시간이 길어집니다. 마지막으로 열을 추가하고 파일 정렬 사용 또는 임시 사용과 같은 단어를 사용하지 마십시오. 이는 성능에 큰 영향을 미칩니다.

인덱스 생성 시 주의할 점

1. 테이블의 인덱스 수를 제한합니다 . 업데이트 작업 수가 많은 테이블의 경우 인덱스 수는 일반적으로 3개를 초과할 수 없으며 최대 5개를 초과할 수 없습니다. 인덱스는 액세스 속도를 향상시키지만 인덱스가 너무 많으면 데이터 업데이트 작업에 영향을 미칩니다.
2. 값이 한 방향으로 증가하는 필드 (예: 날짜 유형 필드)에 인덱스를 구축하지 마십시오. 복합 인덱스의 경우 이러한 유형의 필드를 앞에 배치하지 마십시오. 필드의 값은 항상 한 방향으로 커지기 때문에 항상 인덱스의 마지막 리프 페이지에 새 레코드가 저장되므로 리프 페이지에 대한 접근 경쟁, 새 리프 페이지 할당, 중간 분기 페이지 분할이 지속적으로 발생합니다. 또한, 구축된 인덱스가 클러스터형 인덱스인 경우 테이블의 데이터가 인덱스 순서대로 저장되며 모든 삽입 작업이 마지막 데이터 페이지에 집중되어 삽입 "핫스팟"이 발생합니다.
3. 복합 인덱스의 경우 쿼리 조건에 나타나는 필드의 빈도를 기반으로 인덱스를 생성합니다 . 복합 색인에서는 레코드가 첫 번째 필드를 기준으로 먼저 정렬됩니다. 첫 번째 필드의 값이 동일한 레코드의 경우 시스템은 두 번째 필드의 값에 따라 레코드를 정렬합니다. 따라서 쿼리 조건에는 복합 인덱스의 첫 번째 필드만 나타나며 해당 인덱스를 사용할 수 있습니다. 따라서 적용빈도가 높은 필드를 종합지수 앞에 배치하는 것은 시스템이 이 색인을 최대한 활용하게 하여 지수의 역할을 하게 된다 .
4. 더 이상 사용되지 않거나 거의 사용되지 않는 인덱스를 삭제합니다 . 테이블의 데이터가 대폭 업데이트되거나 데이터 사용 방식이 변경된 후에는 원래 인덱스 중 일부가 더 이상 필요하지 않을 수 있습니다. 데이터베이스 관리자는 정기적으로 이러한 인덱스를 식별하고 삭제하여 인덱스가 업데이트 작업에 미치는 영향을 줄여야 합니다.
5. 쿼리에서 거의 사용되거나 참조되지 않는 열에 대해서는 인덱스를 생성해서는 안 됩니다. 이는 이러한 열이 거의 사용되지 않기 때문에 색인을 생성하거나 색인을 생성하지 않아도 쿼리 속도가 향상되지 않기 때문입니다 . 반대로 인덱스 추가로 인해 시스템 유지 속도가 감소하고 공간 요구 사항이 증가합니다.
6. 동일한 값이 많은 필드에 인덱스를 생성하지 마십시오 . 이는 이러한 컬럼은 인사 테이블의 성별 컬럼과 같이 값이 매우 적기 때문에 질의 결과에서는 결과 세트의 데이터 행이 테이블의 데이터 행 중 큰 부분을 차지하기 때문입니다. 테이블에서 검색해야 할 데이터 행의 비율이 엄청납니다. 인덱스를 늘려도 검색 속도가 크게 향상되지는 않습니다.
7. 텍스트, 이미지 및 비트 데이터 유형으로 정의된 열에 인덱스를 추가하면 안 됩니다 . 이는 해당 컬럼의 데이터 양이 상당히 크거나 값이 매우 적기 때문입니다;
8. 수정 성능이 검색 성능보다 훨씬 높을 경우 인덱스를 생성해서는 안됩니다 . 수정 성능과 검색 성능이 서로 상반되기 때문이다. 인덱스를 추가하면 검색 성능은 향상되지만 수정 성능은 저하됩니다. 인덱스를 줄이면 수정 성능이 향상되고 검색 성능이 저하됩니다. 따라서 수정 성능이 검색 성능보다 훨씬 높을 경우 인덱스를 생성해서는 안 됩니다.

추천

출처blog.csdn.net/qq_45442178/article/details/129711297