옵티마이저와 힌트

요청된 쿼리는 결과가 같아도 결과를 만들어내는 방식은 매우 다양하다. Mysql에서는 Explain으로 쿼리의 실행계획을 확인할 수 있는데, 어떤식으로 최적화되어 실행되었는지 알수있다. 대부분의 DBMS에서는 옵티마이저가 이러한 동작을 담당한다.

Optimizer

옵티마이저는 DB구조중 가장 복잡한 부분으로 알려져 있고, 실행 계획을 이해하는 것 또한 상당히 어렵고 까다롭다 이러한 실행 계획을 이해할 수 있어야, 실행 계획의 불합리한 부분을 찾아내고 쿼리를 좀더 최적화 할 수있다.

Parse Tree 에선 Sql Parser라는 모듈로 문법확인및 서버 Parse tree를 생성한다 get data에서는 데이터 및 테이블을 선택한 후 내용을 가져온다

종류

옵티마이저의 종류는 크게 두종류의 옵티마이저가 존재한다.

규칙 기반 최적화 : 옵티 마이저의 우선도에 따라 실행 계획을 결정한다 비용 기반 최적화 : 여러가지 가능한 방법을 만들고 각 단위 작업의 비용 정보와 예측된 통계를 바탕으로 최소 비용 쿼리를 실행한다

데이처의 처리 방식은 풀 테이블 스캔이나 풀 인덱스 스캔이 주로 사용된다. Innodb의 경우 연속된 데이터 페이지가 읽히면 read Ahead작업으로 필요한 데이터를 미리 버퍼 풀에 가져오게 된다. 처음 데이터는 포그라운드 스레드, 이후는 백그라운드 스레드에서 캐싱 된다.

[full index scan]
> SELECT COUNT(*) FROM employees;
[full table scan]
> SELECT * FROM employees;

처리

병렬 처리 : Mysql 8.0부터는 쿼리의 병렬처리가 가능해졌다 [ innodb_parallel_read_threads ] 라는 시스템 변수로 하나의 쿼리가 처리하는 스레드의 개수를 지정할 수 있다. 단순 조회의 경우에만 사용할 수 있으며, 힌트는 따로 존재하지 않는다.

ORDER BY : 정렬의 처리는 인덱스를 이용하는 방법과 Filesort의 별도의 처리를 하는 방법이 있다 SORT BUFFER : 정렬을 수행하기 위한 별도의 메모리 공간이다. 정렬이 필요한 경우 사용하며, 최대 사용가능한 크기를 시스템변수로 지정할 수 있다

정렬

레코드를 정렬할 때, Sort buffer에 전체를 담을지, 기준을 담을지에 따라서 싱글 패스&투 패스 정렬 모드로 나뉘어지게 된다.

싱글패스 : 전체 대상을 담아 정렬을 수행하는 방식이다. 투패스 : 정렬 대상&키 값만 소트 버퍼에 담아 정렬을 수행

Order By가 사용되면 반드시 다음 처리 방법중 하나로 정렬이 수행된다

방법내용방식

Index

X

Order By가 가장 먼저 읽는 테이블에 맞게, Order by 순서에 맞는 인덱스가 있어야한다

Drive

using, file sort

드라이빙 테이블을 먼저 조회하여 정렬한 뒤 조인을 수행

Temporary

using temporary

2개이상의 테이블을 조인하는 경우, 조인결과를 임시테이블에 저장 후 다시 정렬하는 방식이며, 가장 느리다.

스트리밍 방식 : 레코드가 검색될 때마다 바로바로 클라이언트에 전송해주는 방식이다. 클라이언트가 쿼리를 요청후 곧바로 첫번 째 레코드를 전달받는다. 쿼리가 얼마나 많던지 상관없이 빠른 응답 시간을 보장해 주게 된다.

버퍼링 방식 : order By, Group by는 스트리밍된 결과값을 받을 수 없는데, 모든 레코드를 가져온 후 정렬&그룹화 해야하기 때문이다. 이 시간동안 클라이언트는 작업을 기다려야 하기 때문에 Buffering이라 한다

그룹화

Group by가 있는곳은 Having을 사용할 수 있는데, Group by의 필터링 역할을 수행하며, 인덱스를 사용할 수 없다.

With Index : 드라이빙 테이블에 속한 칼럼을 그룹화 할때는 인덱싱을 읽으며 수행한 후 조인한다.

Without Index : 인덱스 레코드를 건너 뛰면서 필요한 부분만 읽어 가져오는 것이다. [ using index for group-by ] With Temporary : 인덱스를 전혀 사용하지 못하는 경우 사용된다 [ Using Temporary ]

Distinct

유니크한 값을 가져오는 경우 사용하며, 집합함수의 유&무로 구분하여 살펴볼 수 있다.

With select : 단순 조회의 경우 Select Distinct 의 형태를 사용하며 group by와 동일하게 처리된다.

With group function : 조회하는 모든 조합의 유니크한 것들만 가져와 수행한다.

최적화

Last updated