인덱스는 무엇입니까? 인덱스에 의해 MySQL의 쿼리를 최적화하는 방법

1. 색인

      하나의 MySQL의 테이블 번호가 너무 큰 기록 할 때, CRUD 성능이 급격히 감소 될 것입니다. 효율적인 운영이 매우 중요하다을 위해 MySQL을 MySQL의 인덱스를 구축 지수는 크게 MySQL의의 검색 속도를 향상시킬 수 있습니다. 단일 테이블의 데이터는 항상 미래에 상승 계속하지 않는 한, 단지의 분할, 분할이 논리를 가져올 것이다, 구축, 운영 및 유지 보수를 고려 시작되지 않습니다. 천만 이하에서 일반적으로 정수 기반 테이블, 다음 오백 만의 문자열 기반 테이블이 많은 문제가되지 않습니다, 그리고 사실 많은 시간 MySQL은 아직 최적화의 여지 단일 테이블의 성능, 수천만을 지원하는 데이터의 정상적인 양보다 훨씬 더.


인덱스의 장점과 단점 :

장점 : 크게, 서버 종류 및 임시 테이블, 빠른 검색, 랜덤 I을 방지 할 수있는 서버를 검색 할 데이터의 양이 감소 / O는 순차적 I / O 감소 I / O 시간, 빠른 검색되고, 인덱스 그룹 그룹화 및 가속화 될 수 정렬, 정렬;

단점 : 따라서, 상기 인덱스 테이블 자체, 그리고, 저장 공간을 차지 일반적으로 점유되는 인덱스 테이블 공간의 1.5 배의 데이터 테이블은, 유지하고 인덱스 테이블을 작성하는 시간 비용의 데이터 량과 같은 비용 상승을 얻어 ; 인덱스를 구성하는 것은 (추가, 삭제, 수정) 데이터 테이블의 수정 작업은 줄이고 효율성을, 또한 데이터 테이블을 수정하는 동시에 인덱스 테이블을 수정해야하기 때문에 것이다 인덱스를 생성 할 때 테이블을 잠글 필요가 있으므로 실제 비즈니스 운영은 유휴 필요 중.


2. 인덱스 유형

      FULLTEXT, HASH, BTREE, RTREE : MySQL의 존재는 여러 인덱스 유형이 있습니다.

FULLTEXT

      그것은 전체 텍스트 인덱스 만의 MyISAM 엔진을 지원합니다. 그것은 INDEX 사용을 CREATE, ALTER TABLE을, 표를 만들 수 있습니다,하지만 지금 만 CHAR, VARCHAR, TEXT 컬럼 전체 텍스트 인덱스를 만들 수 있습니다.

      의 MyISAM 및 전체 텍스트 인덱싱 함께 태어난되지 않은, "% 단어 %"문제 이름 등의 텍스트 퍼지 검색이 유형의 낮은 효율성을 해결하기 위해 나타납니다.
FULLTEXT (전문) 지수는의 MyISAM과 InnoDB에 대해서만 사용할 수 있습니다

  • 대량의 데이터 세트의 경우, 노 전체 텍스트 인덱스 테이블에 데이터를 추가하고, 첨가 속도는 데이터에 부가되는 것보다 빨리 전체 텍스트 인덱스 테이블 FULLTEXT 인덱스를 가진다.

  • MySQL은 엔진이 다음 전체 텍스트 인덱스가 적용되지 않습니다, 기타 데이터의 경우 이전 5.6 버전의 전체 텍스트 인덱스 만의 MyISAM 스토리지 엔진에 사용할 수와 함께 제공됩니다. InnoDB 스토리지 엔진의 5.6 버전은 전체 텍스트 인덱싱을 지원하기 시작했다 후

  • MySQL의에서 전체 텍스트 인덱싱 분리 영어 현재 중국 아직 지원되지 않습니다 유용합니다. N- 그램을 사용하여 플러그인의 5.7 버전 이후 중국어를 지원하기 시작했다.

  • 문자열을 검색 할 수 없습니다 원하는 결과를 검색 할 수 너무 짧으면 검색 문자를 중지 단어를 포함하는 경우 MySQL의에서, 적어도 4 바이트의 검색 문자열 길이는 또한, 정지 단어는 무시됩니다..

해시시

      인덱스 컬럼 기준값 해시 코드 값 산출 해시 인덱스 후 저장된 값은 해싱 알고리즘을 사용하기 때문에, 대응하는 위치의 해시 코드에 데이터의 행의 물리적 위치를 실행할 수 있으므로 매우 빠른 액세스되지만 값은 하나에 대응 해시 코드, 그리고 단방향 해시를 배포됩니다. (단 거의 100 %) 단, 키 - 값 쌍 HASH 형태 등 때문에 지표로서 적합하다.

      하나를 찾을 수 있습니다 HASH 인덱스 층으로 층으로 트리 인덱스처럼 보이도록해야하고, 따라서 매우 높은 효율이되지 않습니다. 그러나이 효율 즉, 단지 "="와 탐구의 범위에 대한 효과적인 조건 "에서"조건부입니다 주문 및 조합 지수는 여전히 비효율적이다.

BTREE

      BTREE (B + 트리), 트리 구조 (진 트리)에 저장된 데이터마다 쿼리 리프를 구하는 노드를 탐색, 접속 루트 트리에서 시작하는 특정 알고리즘에 따라 인덱스 값에 인덱스의 종류이다. BTREE 잎 이외의 노드는 데이터 (데이터)를 저장, 따라서 리프 노드에 모든 데이터를 확인해야하고, 모든 데이터 쿼리 속도가 동일하도록 리프 노드는 같은 높이하지 않기 때문에. 이것은 MySQL의에서 기본 및 인덱스의 가장 일반적인 유형입니다.

RTREE

      거의 MySQL을 사용되지 RTREE는 만 지오메트리 데이터 유형을 지원하는 스토리지 엔진의 유형은의 MyISAM, BDB, InnoDB에, NDB, 아카이브 몇 가지를 지원합니다.

      BTREE 상대, RTREE 강도는 검색의 범위에있다.


3. 인덱스 종

일반 인덱스 : 만 쿼리 속도.

유일한 인덱스 : 고유의 질의 열 값을 속도 + (널 (null)이있을 수있다).

기본 키 인덱스 : 고유 한 값 쿼리 + 열을 빠르게 + 하나 개의 테이블 (널 (null)이 없습니다).

종합 지수 : 다중 열 값이 인덱스 전용 검색의 조합, 효율 인덱스 병합보다 큰, "가장 왼쪽 접두사"원칙에 따라 가장 일반적으로 내림차순으로, 검색 또는 정렬 왼쪽 열 사용을 구성, 결합 인덱스 아주 COL1, col1col2을 설정, 세 개의 인덱스를 col1col2col3하지만, COL2 또는 COL3이 인덱스를 사용할 수 없습니다.

전체 텍스트 인덱싱 : 텍스트의 내용은 단어 검색을 구분됩니다.


4. 정책 색인


4.1 때 인덱스를 사용 하는가?

  • 기본 키는 자동으로 고유 인덱스를 만들;
  • WHERE 또는 ORDER 종종 쿼리와 BY,
    열 문을 인덱싱 할 나타납니다;
  • 정렬 컬럼으로 인덱싱하는 단계;
  • 쿼리 테이블 및 기타 관련 분야, 외래 키 관계 인덱스
  • 높은 동시 조합 번호 아래 경향;
  • 함수는 예를 들면, 카운트 (column_1)에 필요한 최대 (column_1) column_1하거나 인덱싱 할 중합 열 인덱스에 사용될 수있다.


4.2하지 않을 때는 인덱스를 사용하는?

  • 인덱스 컬럼하지에 자주 추가 및 삭제;
  • 인덱싱되지 않습니다 중복 된 컬럼의 다수가 있습니다;
  • 하지 인덱스 너무 작은 테이블에 기록합니다. 데이터베이스가 이미 충분한 시험 데이터가있는 경우에만, 성능 결과는 실제 기준값이있다. 또는 인덱스를 사용하지 않고 - 테스트 데이터베이스에 기록 된 데이터의 불과 몇 백, 그들은 첫 번째 쿼리의 완료 후 수행하는 경향이 경우 이후의 모든 쿼리 명령은 매우 빠르게 실행하게되는 메모리로로드 . 1000 개 이상의 데이터베이스 레코드가 데이터의 양 또한 MySQL 서버의 메모리의 총량을 초과 한 경우에만, 데이터베이스 성능 테스트 결과는 의미가있다.


인덱스 케이스의 4.3 실패 :

  • 복합 인덱스의 열을 할 수 없음이있는 경우, 그 지수에 대한이 열이 유효하지 않습니다, NULL이다;
  • 다음에 의해 ORDER를 사용하지 않는, WHERE 절에 사용되는 경우 SELECT 문에서 인덱스는 한 번만 사용할 수 있습니다;
  • LIKE 동작은 '%의 단 %가'인덱스를 사용하지 않는, 즉 인덱스는 실패하지만, '단 %'는 인덱스를 사용할 수있다;
  • 예를 들어, 열 인덱스에 실패 인덱스를 사용하여 발현 또는 기능 :
select * from table where ceate_time > unix_timestamp(curdate());

그것은 전체 테이블에 대한 인덱스를 스캔하면서 실패로 이어질 각 줄 작업에 일어날 것이다, 그래서 우리는 매개 변수로 프로그램에 의해 현재의 시간을 변경할 수 있습니다 :

select * from table where ceate_time > 1524561911;

다른 와일드 카드 같은, 즉, 정규 표현식에서 쿼리에 사용 조건이 만 와일드 카드하지 않은 검색 템플릿의 첫 번째 문자의 경우 인덱스를 사용하는 말을하는 것입니다;

  • <심볼> 및 기호를 포함하여, 쿼리 조건에서 동일하지 않습니다 사용! = 지수는 실패로 이어질 것입니다. 특히 : 당신은 기본 키 인덱스를 사용하는 경우! = 인덱스가 실패하지 않을 경우, 기본 키 인덱스 유형 또는 정수 인덱스 <심볼 또는> 심볼 인덱스 실패가 발생하지 않는다. (전체의 매우 작은 비율을 기록하는 경우 <심볼> 심볼 포함되지는 동일하고, 그 후에는 실패하지!);
  • 사용은 쿼리에 NULL IS 또는 실패로 이어질 수 NULL 지수는 아니다;
  • 단일 인용 부호없이 문자열 색인이 실패의 원인이됩니다. 고장의 유형은 모바일 필드와 불일치를 초래할 수 있다고하는 것이 더 정확한 캐릭터 타입이 사용되는 경우, 모바일 = 99999 WHERE 모바일 = '99999'교체해야 장애가 발생할 것이다;
  • 이 때, 쿼리 기준을 사용 또는 인덱스의 오류가 발생할 수있는 여러 조건을 연결, 각각 또는 링크의 조건은 인덱싱하지 않는 한 두 번 쿼리를 변경 한 다음 ALL UNION으로 연결되어야한다
  • 인덱스를 사용하여 정렬 필드가 다음 필드가 필드를 색인 할 것이다 선택하면, 인덱스, 그렇지 않으면 실패합니다. 특히 : 정렬 인 경우 기본 키 인덱스가 * 인덱스에 장애가 발생하지 않습니다를 선택;
  • 우리가해야하는 경우 다중 열 정렬을 포함하지 않도록하려고,이 큐에 대해 복합 인덱스를 작성하는 것이 가장 좋습니다.


4.4 MySQL의 쿼리 최적화 :

필드 :

  • 사용 TINYINT, SMALLINT, MEDIUM_INT 정수 유형을 확인하지 INT와 같은 비 음성 플러스 UNSIGNED 경우;
  • VARCHAR 길이 분포는 정말 공간이 필요합니다;
  • 대신 정수 문자열 또는 열거 형을 사용하는;
  • 대신 DATETIME의 타임 스탬프를 사용해보십시오;
  • 너무 많은 단일 테이블 필드가하지 마십시오, 그것은 20에서 권장;
  • NULL 필드, 쿼리 최적화 및 여분의 공간 색인을 차지하기 어려운를 사용하지 마십시오;
  • 정수로 IP를 저장합니다.

인덱스 :

  • 인덱스 할 수없는 쿼리를 기반으로 타겟팅에 나와 고려 작성하려면 WHERE 및 ORDER 색인 색인 또는 전체 테이블 스캔보고 설명하기에 따라 여부를 사용할 수 있습니다 포함 명령에 의해;
  • 필드가 WHERE 절에서 결정되는 NULL 값으로 피해야한다, 스캔 인덱스 및 전체 테이블을 사용하여 포기 엔진의 원인이됩니다;
  • 값 분포가 성긴 필드는 "성"필드 두 개 또는 세 개의 값으로 인덱스를 구축하기에 적합하지 않다;
  • 문자 필드는 접두사 인덱스를 구축;
  • 문자는 기본 키 필드하지 않는 것이 좋습니다;
  • 프로그램에 의해 보장 없음 외래 키 제약 없다
  • 절차 적 보장에 구속, UNIQUE하지보십시오;
  • 아이디어 질의 시퀀스는 다중 열 인덱스를 사용하는 경우, 불필요한 단일 인덱스 삭제 일치한다.

쿼리는 SQL :

  • SQL은 느린 슬로우 쿼리 로그를 열어 밖으로 찾을 수있다;
  • 산술 열을하지 마십시오 : SELECT ID를 세 + 1 = 10, 열에서 어떤 작업이 데이터베이스 튜토리얼 기능, 쿼리와 등호의 오른쪽에있는 작업을 이동하는 등, 식을 평가를 포함하는 테이블 스캔을 일으킬 것이다 WHERE;
  • 가능한 한 간단하게 SQL 문 :; 잠금 시간을 단축 큰 문 철거 작은 문;에 SQL 만 CPU 동작 큰 SQL 전체 라이브러리가 차단 될 수있다;
  • SELECT * 마십시오
  • 또는 재기록 : 효율 레벨 N OR, 효율이 로그 (n)의 레벨이, IN 200로 제어 제안서의 수;
  • 기능 및 응용 프로그램 구현을 트리거하지 마십시오
  • % XXX 스타일의 질문을 피하고 '%의 XXX의 %는'인덱스를 사용하지 않는 경우는 전체 텍스트 인덱싱 등을 사용할 수 있습니다 :
SELECT * FROM tablename MATCH(index_colum) ANGAINST(‘word’);
  • 이하 가입;
  • 이러한 '123'과 '123'비, 123, 123의 비율과 동일한 유형을 사용하여 비교 하였다;
  • 대부분의 지수 접두사 원칙에 따라, 열 등의 왼쪽에 정렬 및 그룹화 가장 높은 주파수;
  • 인덱스 및 테이블 전체를 스캔!;를 사용하여 포기 또는 WHERE 절 = <> 연산자, 그렇지 않으면 엔진의 사용을 피하십시오
  • IN BETWEEN 사용하지 않고 연속 값의 경우 : SELECT 이드 t 어디서 1~5 BETWEEN NUM;
  • 데이터 테이블의 전체 목록을하지 마십시오 매김에 LIMIT를 사용, 페이지 번호가 너무 큰되지 않습니다;
  • 당신이 접두사 길이를 지정해야합니다 가능하면 짧은 인덱스를 사용합니다. 예를 들어, CHAR (255) 열이있는 경우, 앞 단 다치에서 10 개 또는 20 문자 다음 인덱스를 전체 열을하지 않으면. 짧은 색인 만 검색 속도와 디스크 공간 및 I / O 작업을 저장할 수 없습니다.


4.5 자주 묻는 질문 색인

1, 인덱스는거야?

      지수는 신속하게 행의 열에서 특정 값을 찾는 데 사용됩니다. 인덱스를 사용하지 마십시오, MySQL은 당신이 해당 줄을 찾을 때까지 첫 번째 레코드에서 전체 테이블을 읽기 시작해야합니다. 테이블이 클수록 더 많은 시간이 소요됩니다. 테이블이 쿼리 인덱스의 열이있는 경우, mysql을 신속하게 데이터 파일의 중간을 찾을 수있는 위치에 도달 할 수 있습니다, 모든 데이터를 볼 필요가 없습니다.

      대부분의 MySQL 인덱스 (기본 키 인덱스, 고유 전체 텍스트) 또한 B 트리에 저장되어 있지만, R 트리 인덱스를 사용하는 공간 데이터 유형 및 해시 인덱스 테이블 메모리를 지원한다.


2, 좋은 인덱스 단지, 나는 지수는 더 생생한 예를 들어이 방법을 이해?

      이 사전의 앞에 있다고 상상, 데이터가 책의 텍스트입니다, 당신은 CPU있어, 인덱스는 책의 디렉토리입니다.


3, 더 나은 인덱스?

      대부분의 경우, 지수는 크게 쿼리의 효율성을 향상시킬 수 있습니다. 그러나 :
데이터 변경 (추가 및 삭제는) 인덱스를 유지하기 위해 필요하며, 따라서 이상의 인덱스보다 유지 보수 비용을 의미,
또한 (50 카탈로그가 책 100?) 이상의 제어 공간을 말한다
너무 작은 테이블, 인덱스를 구축하는 것은 (당신이 먼저 디렉토리로 이동해야하는, 브로셔 2 읽어?) 속도가 느려질 수 있습니다


4, 인덱스 필드 유형 문제

      텍스트 형식, 인덱스는 (길이 지정)화할 수있다; 스크린과 인덱스 열은 동일한 데이터 유형의 값을 유지하기 위해 사용; 종합의 MyISAM 스토리지 엔진은 1000 바이트의 길이를 초과 할 수 없다.


5, 인덱스를 사용하려면?

      같은 쿼리를 최소화하지만 인덱스에서 사용할 수있는 'XXX %의'절대적으로 사용할 수 없습니다. 또한 같은, 운영자는 인덱스를 사용할 수 있습니다 :

<,<=,=,>,>=,between,in

인덱스에이 적은 :

<>,not in,!=



6, 필드의 어떤 종류의 인덱스를 구축하기위한 적합하지 않습니다?

      특이 열 값은 인덱스에 적합하지 않다 (성별, 종류 등)도 작다. 데이터 인덱싱에 매우 자주 업데이트되지 않습니다 (어떤 크기는? 일반적으로, 테이블의 15 % 이상으로 데이터의 값은 인덱스를 구축 할 필요가 없습니다).


(7), 쿼리는 여러 인덱스를 사용할 수 있습니까?

      아니


어떻게 인덱스를 작성하는 8, 다중 열 쿼리?

      쿼리는 하나 개의 인덱스하는 인덱스 열 또는 인덱싱 된 열 B를 사용할 수 있습니까? 누가 차별 (이하 동일 값) 내장, 누가 더! 물론, 공동 인덱스는 좋은 프로그램입니다.


9, 공동 인덱스를 발행

-- 命中col1、col2联合索引
select col1,col2 from test where col1 = 'xxx';
-- 不能命中col1、col2联合索引
select col1,col2 from test where col2 = 'xxx';

그래서 대부분의 경우,이 COL1, COL2 인덱스이며, 인덱스 COL1을 구축하지 것이다.


인덱스를 사용할 수 없습니다 일반적인 상황은 무엇입니까 (10)?

like '%xxx'
not in
!=

열은 같은 계산 기능 :

where md5(password) = "xxx"

쿼리가 다른 인덱스를 칠 수없는, 인용 가치를 잃지 않도록 기억입니다 (예 : 전화 번호) 문자열 타입의 필드 값을 유지 :

select * from test where mobile = 13800002222;

모바일 필드는 char 또는 VARCHAR 타입 인 경우, 인덱스를 공격 할 수 위의 쿼리는해야한다 :

select * from test where mobile = '13800002222';


11, NULL 문제

      디자인의 테이블 구조가 NULL의 존재 피해야한다 그래서 널 지수는 존재로 이어질 것입니다.
-1과 같은 다른 방법을 표현하는 데 사용할 수 있습니다.

참조 :
https://blog.csdn.net/liutong123987/article/details/79384395

https://blog.csdn.net/github_26672553/article/details/82887009

https://blog.csdn.net/tongdanping/article/ 자세한 내용은 / 79878302

추천

출처www.cnblogs.com/qingfengEthan/p/11329144.html