mysql 튜닝 인덱스 최적화
기사 디렉토리
1. 사전 : 색인 관련 지식
1. 인덱스 사용 / 장점 / 분류
인덱스 장점 :
1>, 서버가 스캔해야하는 데이터 양을 크게 줄입니다.
2>. 서버가 정렬 및 임시 테이블을 피할 수 있도록 도와줍니다.
3>. 임의의 io를 순차적 io로 전환합니다.
색인 용도 :
1>, WHERE 절과 일치하는 행을 빠르게 찾습니다.
2> 여러 인덱스 중에서 선택할 수 있다면 mysql은 일반적으로 가장 적은 행을 찾는 인덱스를 사용합니다.
3>, 테이블에 다중 열 인덱스가있는 경우 옵티마이 저는 인덱스의 가장 왼쪽 접두사를 사용하여 행을 찾을 수 있습니다.
4>, 테이블 연결이있을 때 다른 테이블에서 행 데이터를 검색합니다.
5>, 특정 인덱스 열의 최소값 또는 최대 값을 찾습니다.
6> 사용 가능한 인덱스의 가장 왼쪽 접두사에서 정렬 또는 그룹화가 수행되면 테이블을 정렬하고 그룹화합니다.
7> 경우에 따라 데이터 행을 쿼리하지 않고 값을 검색하도록 쿼리를 최적화 할 수 있습니다.
인덱스 분류 :
기본 키 인덱스, 고유 인덱스, 일반 인덱스, 전체 텍스트 인덱스, 복합 인덱스
2. 인덱싱 프로세스 현상
테이블로 돌아 가기 : 현재 사용되는 인덱스는 일반 인덱스이고 질의 열은 인덱스 화되지 않은 열입니다. 데이터를 찾으려면 두 단계가 필요합니다. 먼저 일반 인덱스를 통해 기본 키 값을 찾은 다음 기본 키 값 행 레코드에 따라 기본 키 인덱스 (클러스터형 인덱스)를 통해 해당합니다. 다시 테이블 현상은 두 개의 인덱스 스캔 때문에 쿼리 효율성을 감소시킵니다.
·
Covering index : 쿼리 된 필드가 기본 키 + 인덱싱 된 필드 (where 조건에서 인덱싱 된 열의 필드에 의해 쿼리 됨) 일 때 트리거됩니다. 일반 인덱스에 저장된 날짜는 기본 키 ID와 필드 값이기 때문입니다. 예를 들어, 사용자 테이블의 id 열은 기본 키 인덱스이고 이름 열은 일반 인덱스 인 다음 select id, name from user where name = 'zhangsan'; 쿼리는 커버링 인덱스를 트리거합니다.
· 가장
왼쪽 일치 : 전제 조건은 색인을 복합 색인으로 사용합니다. 인덱스 생성시 첫 번째 필드가 질의 조건에서 사용되면 인덱스가 사용됩니다. 복합 색인을 사용할 때 가장 왼쪽 접두사 세트를 따르고 복합 색인을 작성할 때 가장 자주 쿼리되는 조건을 왼쪽에 배치하십시오.
·
인덱스 푸시 다운 : 5.6 이후 인덱스 푸시 다운 후, 이전에 쿼리에 non-primary key 인덱스가 사용되었을 때 스토리지 엔진은 인덱스를 통해 데이터를 검색 한 다음 MySQL 서버로 반환합니다. 데이터가 조건을 충족합니다.
인덱스 푸시 다운 후 인덱싱 된 열에 대한 판단 조건이있을 때 MySQL 서버는 판단 조건의이 부분을 스토리지 엔진에 전달한 다음 스토리지 엔진이 인덱스가 조건을 충족하는지 여부를 판단합니다. MySQL 서버에 의해 전달 된 조건과 인덱스가 조건을 충족 할 때만 데이터가 검색됩니다. 나와서 MySQL 서버로 돌아갑니다.
인덱스 푸시 다운은 스토리지 엔진이 기본 테이블을 쿼리하는 횟수를 줄일 수 있으며 MySQL 서버가 스토리지 엔진에서 데이터를 수신하는 횟수도 줄일 수 있습니다.
3. 인덱스 데이터 구조
인덱스의 특정 데이터 구조는 스토리지 엔진에 따라 다릅니다
메모리 스토리지 엔진 :
스토리지 엔진은 메모리를 기반으로하며 해시 테이블 인덱스 형식을 사용합니다. 해시 저장소를 사용하려면 모든 데이터 파일을 메모리에 추가해야하므로 메모리 공간이 소모됩니다. 쿼리가 동등한 쿼리이면 해시 방법이 매우 빠릅니다.
Mysam / Innodb 스토리지 엔진 :
이 두 가지 유형의 스토리지 엔진의 인덱스 데이터 구조는 B + 트리 구조입니다. B + 트리는 B 트리를 기반으로 한 최적화입니다. 주요 변경 사항 : 1>, B + 트리의 각 노드는 더 많은 노드를 포함 할 수 있습니다. 트리의 높이를 줄이고 데이터 범위를 여러 간격으로 변경하십시오. 간격이 많을수록 데이터 검색 속도가 빨라집니다. 2>, 리프가 아닌 노드는 키를 저장하고 리프 노드는 키와 데이터를 저장합니다. 3> 리프 노드의 두 포인터가 서로 연결되어 있으며 순차 쿼리 성능이 높습니다.
Mysam 스토리지 엔진의 인덱스는 클러스터되지 않은 인덱스이며 인덱스 파일과 데이터 파일이 분리됩니다. 데이터 값은 기본 키에 해당하는 열의 물리적 주소를 저장하고 해당 주소를 통해 해당 행 데이터를 찾을 수 있습니다.
Innodb 스토리지 엔진의 인덱스는 클러스터형 인덱스로, 인덱스 파일은 데이터 파일과 분리되어 있지 않습니다. 데이터 파일 자체는 인덱스 파일이며 모든 데이터 정보는 데이터 필드에 완전히 저장됩니다.
4. 인덱스 매칭 방법
예 : 사용자 테이블에 대한 복합 인덱스 이름, 전화, 나이 생성
전체 값 일치 : 인덱스의 모든 열과 일치 --explain select * from user where name = 'zhangsan'and phone = '13333333333'and age = ' 22 ';
가장 왼쪽 접두사 일치 : 처음 몇 개의 열만 일치-이름 ='zhangsan '및 전화 ='13333333333 '인 사용자로부터 선택 * 설명; 이름 ='zhangsan '인 사용자로부터 선택 * 설명;
열 접두사와 일치 : 특정 열 값의 시작 부분 --explain select * from user where name like'zhang % ';
match range value : find a specific range of data --explain select * from user where name>'zhangsan ' ;
열과 정확히 일치하고 범위는 다른 열과 일치합니다 : 첫 번째 열과 두 번째 열의 일부를 모두 쿼리 --explain select * from user where name = 'zhansgan'and phone> '13333333333';
query that only accesses the index : 커버링 인덱스와 동일합니다.
2. 해시 / (비) 클러스터 / 커버링 인덱스에 대한 설명
1. 해시 인덱스
특징 :
1>, 해시 테이블 구현에 따라 인덱스의 모든 열과 정확히 일치하는 쿼리 만 유효합니다. 범위 쿼리는 지원되지 않습니다.
2> mysql에서는 메모리 스토리지 엔진 만 명시 적으로 해시 인덱스를 지원합니다.
3>, 해시 인덱스 자체는 해당 해시 값만 저장하면되므로 인덱스 구조가 매우 콤팩트하므로 해시 인덱스 검색 속도가 매우 빠릅니다
.4>, 해시 인덱스에는 해시 값과 행만 포함됩니다. 포인터이고 필드 값을 저장하지 않습니다. 인덱스는 행 읽기를 피하기 위해 인덱스의 값을 사용할 수 없습니다
.5>, 해시 인덱스 데이터가 인덱스 값의 순서대로 저장되지 않으므로 정렬 할 수 없습니다.
6> , 해시 인덱스는 부분 열 일치 검색을 지원하지 않습니다. ha 그리스 인덱스는 인덱스 열의 전체 내용을 사용하여 해시 값을 계산합니다
.7>, 해시가 많지 않으면 해시 인덱스의 데이터에 대한 액세스가 매우 빠릅니다. 충돌, 해시 충돌이있는 경우 스토리지 엔진은 모든 링크 된 목록을 통과해야합니다. 적합한 모든 행을 찾을 때까지 행 포인터를 행별로 비교합니다.
애플리케이션 시나리오 :
더 많은 URL이 저장되고 URL을 기반으로하는 검색이 더 많습니다. CRC32를 사용하여 URL을 해시하고 작은 색인을 사용하여 검색을 완료 할 수 있습니다.
2. (비) 클러스터형 인덱스
클러스터형 인덱스 :
데이터 행 및 인접한 키 값의 압축 저장을 나타내는 데이터 저장 방법입니다.
장점 : 관련 데이터를 함께 유지합니다. 인덱스와 데이터가 동일한 트리에 저장되기 때문에 데이터 액세스가 더 빠릅니다. 포함 인덱스 스캔을 사용하는 쿼리는 페이지 노드에서 기본 키 값을 직접 사용할 수 있습니다.
단점 : 1> 클러스터 된 데이터는 IO 집약적 인 응용 프로그램의 성능을 최대화합니다. 데이터가 모두 메모리에 있으면 클러스터형 인덱스는 이점이 없습니다.
2>에서 삽입 속도는 삽입 순서에 크게 좌우되므로 기본 키 순서로 삽입하는 것이 가장 빠른 방법입니다.
3>에서는 업데이트 된 각 행이 새 위치로 이동해야하므로 클러스터형 인덱스 열을 업데이트하는 데 드는 비용이 높습니다.
4> 클러스터형 인덱스 기반 테이블은 새 행이 삽입되거나 기본 키가 업데이트되고 행을 이동해야 할 때 페이지 분할에 직면 할 수 있습니다.
5> 클러스터형 인덱스는 특히 행이 희소하거나 페이지 분할로 인해 데이터 저장소가 연속적이지 않은 경우 전체 테이블 스캔 속도를 늦출 수 있습니다.
비 클러스터형 인덱스 : 데이터 파일은 인덱스 파일과 별도로 저장됩니다.
3. 커버링 인덱스
위에서 언급했듯이 메모리는 커버링 인덱스를 지원하지 않는다는 점에 유의해야합니다.
특징 :
1>. 인덱스 항목은 일반적으로 데이터 행의 크기보다 훨씬 작습니다. 인덱스 만 읽어야하는 경우 mysql은 데이터 액세스 양을 크게 줄입니다.
2>, 인덱스는 열 값의 순서로 저장되기 때문에 IO 집약적 인 범위 쿼리는 디스크에서 각 데이터 행을 무작위로 읽는 IO보다 훨씬 적습니다.
3> MYISAM과 같은 일부 스토리지 엔진은 메모리의 인덱스 만 캐시하고 데이터는 캐싱을 위해 운영 체제에 따라 달라지기 때문에 데이터에 액세스하려면 시스템 호출이 필요하므로 심각한 성능 문제가 발생할 수 있습니다.
4>, INNODB의 클러스터형 인덱스로 인해 커버링 인덱스는 INNODB 테이블에 특히 유용합니다.
세, 인덱스 최적화
1. 작은 세부 사항의 특정 최적화
쿼리에 인덱스 열을 사용할 때 표현식을 사용하지 말고 데이터베이스 계층 대신 비즈니스 계층에 계산을 넣으십시오.
2>, 기본 키 쿼리가 테이블 쿼리로 다시 트리거되지 않으므로 다른 인덱스 대신 기본 키 쿼리를 사용하십시오.
3>, 접두사 색인을 사용하십시오. 필드가 더 길면 열의 시작 부분에있는 부분 문자열을 인덱스 변경 테이블 테이블 이름 추가 키 (필드 이름 (6))로
사용하고 4> 인덱스 스캔을 사용하여 정렬합니다. 행 정렬 및 찾기를 모두 충족하려면 가능한 한 동일한 인덱스를 사용하십시오. 인덱스의 열 순서가 order by 절의 순서와 정확히 같고 모든 열이 같은 방식으로 정렬되면 mysql은 인덱스를 사용하여 결과를 정렬 할 수 있습니다 (가장 왼쪽 접두사의 요구 사항을 충족해야 함). .
5>, Union all, in 또는 인덱스를 사용할 수있는 경우 in을 사용하는 것이 좋습니다.
6>, 범위 열은 인덱스를 사용할 수 있지만 범위 열 뒤의 열은 인덱스를 사용할 수 없으며 인덱스는 최대 하나의 범위 열에 사용됩니다. (<, <=,>,> =, between)
7>, 강제 유형 변환은 전체 테이블
8>을 스캔 하고 업데이트가 매우 빈번하며 데이터 차별성이 낮은 필드에 인덱스를 작성하는 데 적합하지 않습니다. 그 이유는 업데이트가 B + 트리를 변경하고 자주 업데이트되는 필드를 인덱싱하면 데이터베이스 성능이 크게 저하되기 때문입니다. 일반적으로 인덱스는 식별도가 80 % 이상일 때 생성 할 수 있으며, 식별 정도는 count (distinct (column name)) / count (*)를 사용하여 계산할 수 있습니다.
9>. 인덱스 열을 생성합니다. null이 될 수 없으며 예기치 않은 결과가 발생할 수 있습니다.
10> 테이블을 조인해야하는 경우 세 테이블을 초과하지 않는 것이 가장 좋으며 조인해야하는 필드의 데이터 유형은 일관성이 있어야합니다.
11>, 제한을 사용할 수있는 경우 제한
12>를 사용해보십시오 . 단일 테이블 인덱스는 5 개 이내로 제어하는 것이 좋습니다. 복합 인덱스의 인덱스 필드 수는 5 개를 초과 할 수 없습니다.
요약하자면
인덱스 최적화는 테이블 및 관련 쿼리 작업을위한 것이며 조기 최적화가 필요하지 않습니다. 이는 인덱싱 최적화시 실행 계획을 고려할 때 특히 중요합니다.