[MySql] 스토리지 엔진, 인덱스 및 최적화

하나, 스토리지 엔진

MySql5.0에서 지원하는 스토리지 엔진에는 InnoDB, MyISAM, BDB, MEMORY, MERGE, EXAMPLE, NDB Cluster, ARCHIVE, CSV, BLACKHOLE, FEDERATED 등이 포함되며 InnoDB 및 BDB는 트랜잭션 보안 테이블을 제공하고 다른 스토리지 엔진은 비트랜잭션 보안 테이블 .

MySQL5.5之前的默认存储引擎是MyISAM,5.5之后就改为了InnoDB。

둘째, 다양한 스토리지 엔진 특성

특징 이노디비 MyISAM 메모리 병합
저장 한도 64TB 가지다 가지다 아니요
트랜잭션 보안

지원하다

잠금 메커니즘 행 잠금(높은 동시성에 적합) 테이블 잠금 테이블 잠금 테이블 잠금
B-트리 인덱스 지원하다 지원하다 지원하다 지원하다
해시 인덱스 지원하다
전체 텍스트 인덱스 지원됨(버전 5.6 이후) 지원하다
클러스터 인덱스 지원하다
데이터 인덱스 지원하다 지원하다
인덱스 캐시 지원하다 지원하다 지원하다 지원하다
데이터 압축 가능 지원하다
공간 사용 높은 낮은 해당 없음 낮은
메모리 사용량 높은 낮은 중간 낮은
대량 삽입 속도 낮은 높은 높은 높은
외래 키 지원 지원하다

다음은 가장 일반적으로 사용되는 두 가지 엔진인 InnoDB, MyISAM에 중점을 둡니다.

1.이노디비:

InnoDB 스토리지 엔진은 Mysql5.5 이후의 기본 스토리지 엔진입니다.InnoDB 스토리지 엔진은 커밋, 롤백 및 충돌 복구 기능을 통해 트랜잭션 보안을 제공합니다.쓰기 처리 효율성이 낮고 데이터를 유지하기 위해 더 많은 디스크 공간을 차지하며 색인;

InnoDB 스토리지 엔진은 다른 스토리지 엔진과 다릅니다: 트랜잭션 제어, 외래 키 제약 ;

InnoDB 스토리지 엔진 스토리지 방법:

Ⅰ. 공유 테이블 공간 저장소 사용 이 방법의 테이블 구조는 .frm 파일에 저장되고 데이터와 인덱스는 innodb_data_home_dir 및 innodb_data_file_path로 정의된 테이블 공간에 저장되며 여러 파일이 될 수 있습니다.

Ⅱ.Multi-table space storage를 이용하여 이렇게 생성된 테이블의 테이블 구조는 그대로 .frm 파일에 있지만, 각 테이블의 데이터와 인덱스는 .ibd에 별도로 저장된다.

2.MyISAM:

MyISAM은 트랜잭션을 지원하지 않으며 외래 키도 지원하지 않습니다 .장점은 액세스 속도가 빠르며 트랜잭션의 무결성에 대한 요구 사항이 없거나 선택, 삽입 기반 응용 프로그램은 기본적으로 이 엔진을 사용하여 테이블을 생성할 수 있다는 것입니다.

MyISAM 스토리지 엔진 스토리지 방법:

각 MyISAM은 파일 이름과 테이블 이름이 같지만 확장자가 다음과 같은 3개의 파일을 디스크에 저장합니다.

.frm(스토리지 테이블 정의);

.MYD(MYData, 스토어 데이터);

.MYI(MYIndex, 스토리지 인덱스);

셋째, 스토리지 엔진의 선택

스토리지 엔진을 선정할 때 적용 시스템의 특성에 따라 적절한 스토리지 엔진을 선정해야 한다. 복잡한 애플리케이션 시스템의 경우 실제 상황에 따라 조합을 위해 여러 스토리지 엔진을 선택할 수도 있습니다. 다음은 일반적으로 사용되는 여러 스토리지 엔진의 사용 환경입니다.

  • InnoDB: 트랜잭션 처리 애플리케이션에 사용되는 Mysql5.5 이후의 기본 스토리지 엔진이며 외래 키를 지원합니다. 애플리케이션이 트랜잭션의 무결성에 대한 요구 사항이 상대적으로 높고 동시 조건에서 데이터 일관성이 필요하며 데이터 작업에 삽입 및 쿼리 외에도 많은 업데이트 및 삭제 작업이 포함되는 경우 InnoDB 스토리지 엔진이 더 적합한 선택입니다. InnoDB 스토리지 엔진은 삭제 및 업데이트로 인한 잠금을 효과적으로 줄일 뿐만 아니라 트랜잭션의 완전한 제출 및 롤백을 보장합니다.청구 시스템 또는 금융 시스템과 같이 높은 데이터 정확도 요구 사항이 있는 시스템의 경우 InnoDB가 가장 적합한 선택입니다.

  • MyISAM: 응용 프로그램이 주로 읽기 및 삽입 작업이고 업데이트 및 삭제 작업이 거의 없고 트랜잭션 무결성 및 동시성에 대한 요구 사항이 그다지 높지 않은 경우 이 스토리지 엔진을 선택하는 것이 매우 적합합니다.

넷째, 인덱스

1. 인덱스 구조

인덱스 구조 설명하다
B+트리 인덱스 가장 일반적인 인덱스 유형으로 대부분의 인덱스가 B+ 트리 인덱스를 지원합니다.
해시 인덱스 메모리 엔진에서만 지원되며, 기본 데이터 구조는 해시 테이블로 구현되며 인덱스의 모든 열과 정확히 일치하는 쿼리만 유효하며 범위 쿼리는 지원되지 않습니다.
R-트리(공간 인덱스) 공간 인덱스는 주로 지리 공간 데이터 유형에 사용되는 MyISAM 엔진의 특수 인덱스 유형으로 일반적으로 덜 사용됩니다.
전체 텍스트(전체 텍스트 인덱스) 전체 텍스트 색인은 Lucene, Solr, ES와 유사하게 색인에서 값을 비교하는 것이 아니라 텍스트에서 키워드를 찾습니다.

2. 지수 분류

(속성별)

분류 의미 특징 키워드
기본 키 인덱스 테이블의 기본 키에 생성된 인덱스 기본적으로 자동 생성, 하나만 주요한
고유 인덱스 동일한 테이블의 데이터 열에서 중복 값 방지 여러 개 가질 수 있습니다 고유한
일반 인덱스 특정 데이터를 빠르게 찾기 여러 개 가질 수 있습니다
전체 텍스트 인덱스 전체 텍스트 색인은 색인의 값을 비교하는 것이 아니라 텍스트에서 키워드를 찾습니다. 여러 개 가질 수 있습니다 전문


(데이터 저장 방식에 따름)

분류 의미 특징 인덱스 구조
클러스터형/클러스터형 인덱스 인덱스에 데이터를 저장하고 함께 넣으면 인덱스 구조의 리프 노드는 행 데이터를 저장합니다. 있어야 하고 단 하나
비클러스터형 인덱스/보조 인덱스/보조 인덱스 인덱스와 별도로 데이터를 저장하고 인덱스 구조의 리프 노드는 해당 기본 키와 연결됩니다. 여러 개가 있을 수 있습니다.

3. 인덱스 오류 방지

Ⅰ.인덱스의 모든 열에 대해 특정 값을 지정하는 글로벌 매칭.

Ⅱ.열이 여러 개일 경우 가장 왼쪽 접두사 규칙을 따라야 한다. 즉, 쿼리는 인덱스의 가장 왼쪽 앞 열에서 시작하며 인덱스의 열을 건너뛸 수 없습니다.

Ⅲ.범위 질의 우측 칼럼은 인덱스를 사용할 수 없다.

Ⅳ. 인덱스 열에 대한 작업을 수행하지 마십시오. 그렇지 않으면 인덱스가 실패합니다.

Ⅴ. 작은따옴표가 없는 문자열은 인덱스 실패를 유발합니다.

Ⅵ.covering index를 사용하고 select *의 사용을 줄여보지만 쿼리 컬럼이 index 컬럼을 초과하면 성능이 저하된다.

Ⅶ or로 구분되는 조건, or 앞의 조건에 인덱스가 있고 그 다음 열에 인덱스가 없으면 해당 인덱스를 사용하지 않는다.

Ⅷ.%로 시작하는 유사 퍼지 질의는 인덱스 무효, 테일 퍼지 매치일 경우 인덱스 유효하지 않음, 헤드 퍼지 매치일 경우 인덱스 무효

Ⅸ mysql이 full table보다 느린 index를 사용하여 평가하는 경우 index는 적용되지 않는다.

Ⅹ.는 null, is not null 인 경우 인덱스가 유효하지 않은 경우가 있고, in, not in인 경우 인덱스가 유효하지 않은 경우가 있습니다.

4. 지수 설계 원칙

  • 쿼리 빈도가 높고 데이터 양이 많은 테이블의 경우.

  • 인덱스 필드 선택을 위해서는 where 절의 조건에서 최적의 후보 컬럼을 추출해야 합니다.

  • 고유 지수를 사용하여 식별 정도가 높을수록 지수 사용의 효율성이 높아집니다.

  • 인덱스는 데이터 쿼리의 효율성을 효과적으로 향상시킬 수 있지만 인덱스의 수가 항상 좋은 것은 아니며 인덱스가 많을수록 인덱스 유지 비용이 자연스럽게 증가합니다.

  • 인덱스가 짧은 경우 인덱스를 생성한 후 하드디스크에 저장하기도 하므로 인덱스 액세스의 I/O 효율성을 높이면 전체 액세스 효율성도 높일 수 있습니다.

  • 가장 복합적인 인덱스를 사용하여 N 개의 열로 구성된 복합 인덱스는 N 개의 인덱스를 만드는 것과 같습니다 인덱스를 구성하는 처음 몇 개의 필드를 쿼리할 때 where 절에 사용하면 이 쿼리 SQL을 사용할 수 있습니다 인덱스를 결합하여 개선 쿼리 효율성.

建议使用复合索引,少使用单列索引。

다섯, SQL 최적화

먼저 SQL 문의 순서를 살펴보십시오.

编写顺序
SELECT DISTINCT
	<select list>
FROM
	<left_table> <join_type>
JOIN
	<right_table> ON <join_condition>
WHERE
	<where_condition>
GROUP BY
	<group_by_list>
HAVING
	<having_condition>
ORDER BY
	<order_by_condition>
LIMIT
	<limit_params>

-----------------------------------------------------------------------------------------

执行顺序
FROM	<left_table>

ON 		<join_condition>

<join_type>		JOIN	<right_table>

WHERE		<where_condition>

GROUP BY 	<group_by_list>

HAVING		<having_condition>

SELECT DISTINCT		<select list>

ORDER BY	<order_by_condition>

LIMIT		<limit_params>

1. 삽입문 최적화

동시에 많은 데이터 행을 테이블에 삽입해야 하는 경우 다중 값 테이블의 삽입 문을 사용해야 합니다.이 방법은 클라이언트와 데이터베이스 간의 연결과 닫기 소비를 크게 줄입니다. 데이터는 가능한 한 많이 삽입되어야 함 시퀀스 삽입;

2. order by 문 최적화

먼저 두 가지 정렬 방법에 대해 이야기하겠습니다.

Ⅰ: 데이터를 반환하여 정렬하는 것, 즉 일반적인 파일 정렬 정렬로서 정렬 결과를 인덱스를 통해 직접 반환하지 않는 모든 정렬을 FileSort 정렬이라고 합니다.

Ⅱ: 정렬된 인덱스가 직접 리턴한 정렬된 데이터를 순차적으로 스캔하는 방식으로 별도의 정렬이 필요 없고 운용 효율이 높은 인덱스를 사용한다.

두 가지 정렬 방법을 이해한 후 최적화 목표는 명확합니다. 추가 정렬을 최소화하고 정렬된 데이터를 인덱스를 통해 직접 반환합니다. 여기서 condition 및 order by는 동일한 인덱스를 사용하고 order by는 인덱스 order와 동일합니다. order by 필드는 오름차순 또는 내림차순입니다. 그렇지 않으면 추가 작업이 반드시 필요하므로 FileSort가 나타납니다.

FileSort의 경우 mysql에는 두 가지 정렬 알고리즘이 있습니다. 하나는 (2 스캔 알고리즘): 먼저 조건에 따라 정렬 필드와 행 포인터 정보를 제거한 다음 정렬 버퍼에서 정렬합니다.정렬 버퍼가 충분하지 않으면 임시 테이블에 정렬 정렬된 결과는 테이블에 저장됩니다. 정렬이 완료된 후 행 포인터에 따라 레코드를 다시 테이블로 읽어 많은 수의 무작위 I/O 작업을 유발할 수 있습니다. 다른 하나는 (일회성 스캐닝 알고리즘) 조건에 맞는 모든 필드를 한 번에 제거한 다음 정렬 버퍼에서 정렬한 후 바로 결과 집합을 출력하는 것입니다. 정렬의 메모리 오버헤드는 크지만 정렬 효율은 2스캔 알고리즘보다 높습니다.

MySQL은 시스템 변수 max_length_for_sort_data의 크기와 Query 문에서 추출한 필드의 전체 크기를 비교하여 정렬 알고리즘인지 판단하며, max_length_for_sort_data가 크면 두 번째 최적화 알고리즘을 사용하고 그렇지 않으면 첫 번째 알고리즘을 사용합니다.

sort_buffer_size 및 max_length_for_sort_data 시스템 변수를 적절하게 늘려 정렬 영역의 크기를 늘리고 정렬 효율성을 높일 수 있습니다.

3. group by 문 최적화

group by는 실제로 정렬 작업도 수행하기 때문에 order by에 비해 주로 정렬 후 그룹화 작업이 더 많습니다. 물론 그룹화에 일부 집계 함수를 사용하면 일부 집계 함수도 계산되므로 구현에서 그룹별로 색인을 사용할 수도 있습니다.

쿼리에 group by가 포함되어 있지만 사용자가 정렬된 결과를 사용하지 않으려는 경우 order by null을 실행하여 정렬을 비활성화할 수 있습니다.

4. 중첩 쿼리 최적화

Mysql4.1 버전 이후에는 SQL 하위 쿼리가 지원됩니다. 이 기술은 SELECT 문을 사용하여 단일 열 쿼리 결과를 만든 다음 이 결과를 다른 쿼리에서 필터 조건으로 사용합니다. 하위 쿼리를 사용하면 한 번에 완료하기 위해 논리적으로 여러 단계가 필요한 많은 SQL 작업을 완료할 수 있으며 트랜잭션 또는 테이블 잠금을 방지할 수 있으며 쓰기도 쉽습니다. 그러나 경우에 따라 하위 쿼리를 보다 효율적인 연결(JOIN)로 대체할 수 있습니다.

5. 최적화 또는 조건화

OR을 포함하는 질의절의 경우 인덱스를 사용하려면 OR 사이의 각 조건 열에 대해 인덱스를 사용해야 하며 복합 인덱스는 사용할 수 없으며 인덱스가 없으면 인덱스 추가를 고려해야 합니다. or 대신 union을 사용하는 것이 좋습니다.

6. SQL 힌트 사용

SQL 프롬프트는 데이터베이스를 최적화하는 중요한 수단으로, 간단히 말해서 작업 최적화 목적을 달성하기 위해 SQL 문에 인위적인 프롬프트를 추가하는 것입니다.

1. 쿼리 문의 테이블 이름 뒤에 use index를 추가하여 MySQL이 참조할 인덱스 목록을 제공하여 MySQL이 더 이상 사용 가능한 다른 인덱스를 고려하지 않도록 합니다.

select * from tb_user use index(idx_seller_name) where name = 'zhangsan';

2. 사용자가 단순히 MySQL이 하나 이상의 인덱스를 무시하기를 원하는 경우 인덱스 무시를 힌트로 사용할 수 있습니다.

select * from tb_user ignore index(idx_seller_name) where name = 'zhangsan';

3. MySQL이 특정 인덱스를 사용하도록 강제하려면 쿼리에서 힌트로 force index를 사용합니다.

select * from tb_user force index(idx_seller_name) where name = 'zhangsan';

추천

출처blog.csdn.net/qq_42990433/article/details/121767859