Client
- 복수 건의 레코드를 한번의 호출
- 두 개의 쿼리 하나로 통합
- JDBC Statement PreparedStatement 세 단계 (쿼리 문장 분석 -> 컴파일 -> 실행)
- DB Connection Pool 사용하여 대기 시간 Low
- Fetchsize 조정하거나 Paging
Database Engine
- 파일 시스템에 저장된 데이터 조회 시 메모리에 저장 (캐싱)
- 서버 파라미터 튜닝
SQL 쿼리 동작방식
1. Query Caching - MySQL 8.0 부터 제거
2. Parsing - SQL문을 서버가 이해할 수 있도록 쪼개고, 문법확인
3. Preprocessor - SQL문을 서버가 이해할 수 있도록 쪼개고, 문법확인
4. Optimization - 실행계획 수립
5. Handler - 실행엔진의 요청에 따라 데이터를 디스크로 저장/요청
테이블에서 데이터 찾기
- Table Full Scan: Sequential Access, Multi Block I/O를 통해 효율적으로 디스크 읽기
- Index Range Scan: Random Access, Single Block I/O로, 레코드 하나 읽기 위해 매번 I/O
튜닝 절차
1. 일단 조회해보기
- 의도한 결과 맞는지 확인
- 조회 건수, fetch time/duration time 등 확인
2. 개선 대상 파악하기
- 실행 계획 확인
- 조건절, 조인/서브쿼리 확인, 정렬 확인
- 인덱스 현황 파악
3. 개선
실행계획
- MySQL 워크벤치에서 실행계획 확인 가능. 칼럼별로 무슨 뜻인지 살펴보자
- id
- SQL 문이 수행되는 순서
- Driving/Driven 테이블 확인
- select_type
- SIMPLE: 단순한 SELECT문
- PRIMARY: 서브쿼리를 감싸는 외부쿼리
- SUBQUERY: 독립적으로 수행하는 서브쿼리
- DERIVED: FROM 절에 작성된 서브쿼리
- UNION: UNION, UNION ALL로 합쳐진 SELECT
- DEPENDENT SUBQUERY: 서브쿼리가 바깥쪽 SELECT 쿼리에 정의된 칼럼
- DEPENDENT UNION: 외부에 정의된 칼럼으 UNION으로 결합된 쿼리에서 사용
- type
- all: 테이블 풀 스캔
- range: 인덱스 레인지 스캔
- index: 인덱스 풀 스캔
- ref: eq_ref와 같으나 데이터가 2건 이상
- eq_ref: 조인 수행시 드리븐 테이블의 데이터에 PK 혹은 고유 인덱스로 단 1건의 데이터 조회
- const: 조회되는 데이터가 단 1건일때
- system: 테이블에 데이터가 없거나 한 개만 존재
- extra
- Distinct: 중복 제거시
- Using Where: WHERE 절로 필터
- Using temporary: 임시 테이블 생성
- Using Index: 물리적인 데이터 파일 안 읽고, 인덱스만 읽어서 처리
- Using filesort: 정렬시
- [추구해야 할 방향!]
- select_type: SIMPLE, PRIMARY, DERIVED
- type: system, const, eq_ref
- extra: Using index