참고) https://velog.io/@ddangle/Database-MySQL-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98
https://hoing.io/archives/2478
https://velog.io/@klm03025/Real-MySQL-%EC%A0%95%EB%A6%AC-4%EC%9E%A5-%EC%95%84%ED%82%A4%ED%85%8D%EC%B3%90

CREATE TABLE test_table(fd1 INT, fd2 INT) ENGINE=INNODB;
포그라운드 스레드 (클라이언트 스레드)
- MySQL서버에 접속된 클라이언트의 수만큼 존재한다
- 주로 각 클라이언트가 요청하는 쿼리 문장을 처리한다
- 사용자가 작업을 마치고 커넥션을 종료하면 해당 커넥션을 담당하던 스레드는 다시 스레드 캐시로 돌아간다
- 데이터를 MySQL의 데이터 버퍼나 캐시로부터 가져오며, 버퍼나 캐시가 없는 경우는 직접 디스크의 데이터나 인덱스의 파일로부터 데이터를 읽어와서 작업을 처리한다
- InnoDB 테이블은 데이터 버퍼나 캐시까지만 처리하고, 나머지 버퍼로부터 디스크까지 기록하는 작업은 백그라운드 스레드가 처리한다
- MyISAM은 모두 포그라운드 스레드가 처리한다
백그라운드 스레드
- InnoDB에서는 읽기작업은 주로 포그라운드 스레드에서 처리되기 때문에, 읽기 스레드는 많이 설정할 필요 없지만, 쓰기 스레드는 많은 작업을 백그라운드로 처리하기 때문에 여유롭게 설정
- 데이터 쓰기 작업은 JPA의 쓰기 지연 저장소처럼 지연될 수 있지만 읽기 작업은 지연불가
- InnoDB에서도
Insert, Update, Delete같이 데이터를 변경하는 작업은 디스크에 완전히 저장될 때까지 기다리지 않아도 된다

글로벌 메모리 영역
- 모든 메모리 공간은 MySQL서버가 시작되면서 운영체제로부터 할당된다
- 포그라운드 스레드와 무관하게 하나의 메모리 공간만 할당하고 생성된 글로벌 메모리 영역이 N개라고 하더라도, 모든 스레드에 의해 공유된다
- 대표적인 글로벌 메모리 영역
- 테이블 캐시
- InnoDB 버퍼풀
- InnoDB 어댑티브 해시 인덱스
- InnoDB 리두 로그 버퍼
로컬 메모리 영역 (세션메모리 영역)
- 포그라운드 스레드가 쿼리를 처리하는데 사용되는 메모리 영역
- 대표적으로 커넥션 버퍼와 정렬버퍼 등이 있다
- 사용자가 MySQL서버에 접속하면, MySQL 서버에서는 클라이언트 커넥션으로부터 요청을 처리하기 위해 스레드를 하나씩 할당하게 되는데,
클라이언트 스레드(포그라운드 스레드)가 사용하는 메모리 공간이라고 해서클라이언트 메모리 영역이라고도 한다- 각 클라이언트 스레드별로 독립적으로 할당되며, 절대 공유되어 사용되지 않는다
- 각 쿼리의 용도별로 공간이 할당되고 필요하지 않는 경우에는 MySQL이 메모리 공간을 할당조차도 하지 않을 수 있다
- 커넥션이 열려있는 동안 계속 할당된 상태로 남아있는 공간
- 커넥션 버퍼
- 결과 버퍼
- 쿼리를 실행하는 순간에만 할당했다가 해제되는 공간
- 조인 버퍼
- 소트 버퍼
Group by나 Order By등 복잡한 처리는 스토리지 엔진 영역이 아니라 쿼리 실행기에서 처리된다
쿼리 실행 구조
- 쿼리 파서
- 쿼리 문장을 쿼리로 분리해 트리 형태의 구조로 만들어낸다
- 쿼리 문장의 기본 문법 오류는 이 과정에서 발견되고 오류 메시지를 사용자에게 전달
- 전처리기
- 파서트리를 기반으로 쿼리 문장에 구조적인 문제점이 있는지 파악
- 접근권한및 객체 존재여부를 확인해서 거른다
- 옵티마이저
- 가장 중요한 과정
- 쿼리 문장을 저렴한 비용으로 가장 빠르게 처리하는 것을 결정하는 담당
- DBMS의 두뇌
- 실행 엔진
- 옵티마이저가 두뇌라면 실행 엔진과 핸들러는 손과 발에 비유된다
- 만들어진 계획대로 각 핸들러에게 요청해서 받은 결과를 또 다른 핸들러 요청을 입력으로 연결하는 역할
- 핸들러 (스토리지 엔진)
- MySQL 실행 엔진의 요청에 따라 데이터를 디스크로 저장하고 읽어오는 역할
select count(*) 명령시 빠르고, select 명령시에도 빠른 속도를 제공한다