옵티마이저와 힌트 1 정렬 알고리즘 레코드를 정렬할 때 레코드 전체를 소트 버퍼에 담을지 또는 정렬 기준 컬럼만 소트 버퍼에 담을지에 따라 "싱글 패스(Single-pass)"와 "투 패스(Tow-pass)" 두 가지 정렬 모드로 나눌 수 있다. 최신 버전에서는 일반적으로 싱글 패스 정렬 방식을 주로 사용하지만, 아래의 경우에는 싱글 패스 정렬 방식을 사용하지 못하고, 투 패스 정렬 방식을 사용한다. 레코드의 크기가 max_length_for_sort_data 시스템 변수에 설정된 값보다 클 때 BLOB이나 TEXT 타입의 칼럼이 SELECT 대상에 포함할 때 싱글 패스 정렬 방식 소트 버퍼에 정렬 기준(ORDER BY) 칼럼을 포함해 SELECT 대상이 되는 칼럼 전부를 담아서 정렬을 수행하는 방식이다..
MySQL에서 쿼리를 최적으로 실행하기 위해 각 테이블의 데이터가 어떤 분포로 저장되어 있는지 통계 정보를 참조하며, 그러한 기본 데이터를 비교해 최적의 실행 계획을 수립하는 작업이 필요하다. MySQL 서버를 포함한 대부분의 DBMS에서는 옵티마이저가 이러한 기능을 담당한다. 쿼리 실행 절차 MySQL 서버에서 쿼리가 실행되는 과정은 크게 세 단계로 나눌수 있다. 사용자로부터 요청된 SQL 문장을 잘게 쪼개서 MySQL 서버가 이해할 수 있는 수준으로 분리(파스 트리)한다. SQL의 파싱 정보(파스 트리)를 확인하면서 어떤 테이블로부터 읽고 어떤 인덱스를 이용해 테이블을 읽을지 선택한다. 두 번째 단계에서 결정된 테이블의 읽기 순서나 선택된 인덱스를 이용해 스토리지 엔진으로부터 데이터를 가져온다. 첫 ..
인덱스 1은 여기에서 확인하실 수 있습니다. 클러스터링 인덱스 클러스터링 인덱스는 테이블의 프라이머리 키에 대해서만 적용되는 내용이다. 즉, 프라이머리 키 값이 비슷한 레코드끼리 묶어서 저장하는 것을 클러스터링 인덱스라고 표현한다. 여기서 중요한 것은 프라이머리 키 값에 의해 레코드의 저장 위치가 결정된다는 것이다. 프라이머리 키 값이 변경된다면 그 레코드의 물리적인 저장 위치가 바뀌어야 한다는 것을 의미한다. 일반적으로 InnoDB와 같이 항상 클러스터링 인덱스로 저장되는 테이블은 프라이머리 키 기반의 검색이 매우 빠르지만, 레코드의 저장이나 프라이머리 키의 변경이 상대적으로 느리다는 특징이 있다. 위 그림의 클러스터링 인덱스 구조를 보면 클러스터링 테이블의 구조 자체는 일반 B-Tree와 비슷하지만,..
랜덤 I/O와 순차 I/O 랜덤 I/O라는 표현은 하드 디스크 드라이브의 플래터(원판)을 돌려서 읽어야 할 데이터가 저장된 위치로 디스크 헤더를 이동시킨 다음 데이터를 읽는 것을 의미하는데, 사실 순차 I/O 또한 이 작업 과정은 동일하게 이루어진다. 디스크에 데이터를 쓰고 읽는 데 걸리는 시간은 디스크 헤더를 움직여서 읽고 쓸 위치로 옮기는 단계에서 결정된다. 위 그림에서 순차 I/O는 디스크에 기록해야 할 위치를 찾기 위해 디스크의 헤드를 1번 움직였고, 랜덤 I/O는 디스크 헤드를 3번 움직였는데, 이는 순차 I/O는 랜덤 I/O보다 거의 3배 정도 빠르다고 볼 수 있다. 따라서 여러 번 쓰기 또는 읽기를 요청하는 랜덤 I/O 작업이 작업 부하가 훨씬 더 크다. 대부분의 작업은 이러한 작은 데이터를..
MySQL 5.7 버전부터 지원되기 시작한 데이터 암호화 기능은 처음에는 데이터 파일(테이블스페이스)에 대해서만 암호화 기능이 제공됐지만, MySQL 8.0으로 업그레이드되면서 데이터 파일뿐만 아니라 리두 로그나 언두 로그, 복제를 위한 바이너리 로그 등도 모두 암호화 기능을 지원하기 시작했다. MySQL 서버의 데이터 암호화 MySQL 서버의 암호화 기능은 아래 그림과 같이 데이터베이스 서버와 디스크 사이에 데이터 읽고 쓰기 지점에서 암호화 또는 복호화를 수행하기 때문에, 디스크 입출력 이외의 부분에서는 암호화 처리가 전혀 필요하지 않다. 즉, MySQL 서버(InnoDB 스토리지 엔진)의 I/O 레이어에서만 데이터의 암호화 및 복호화 과정이 실행되는 것이다. MySQL 서버에서 사용자의 쿼리를 처리하..
MySQL 서버에서 디스크에 저장된 데이터 파일의 크기는 일반적으로 쿼리의 처리 성능과도 직결되지만 백업 및 복구 시간과도 밀접하게 연결된다. 디스크의 데이터 파일이 크면 클수록 쿼리를 처리하기 위해서 더 많은 데이터 페이지를 InnoDB 버퍼 풀로 읽어야 할 수도 있고, 새로운 페이지가 버퍼 풀로 적재되기 때문에 그만큼 더티 페이지가 더 자주 디스크로 기록돼야 한다. 그리고 데이터 파일이 크면 클수록 백업 시간이 오래 걸리며, 복구하는 데도 그만큼의 시간이 걸린다. 때문에 많은 DBMS에서 이런 문제를 해결하기 위해 데이터 압축 기능을 제공한다. MySQL 서버에서 사용 가능한 압축 방식은 크게 테이블 압축과 페이지 압축의 두 가지 종류로 구분할 수 있는데, 두 방식은 매우 다르게 작동하므로 하나씩 구..
트랜잭션 및 잠금에 관한 내용은 여기에서 확인하실 수 있습니다. 트랜잭션의 격리 수준(Isolation Level)이란, 여러 트랜잭션이 동시에 처리될 때 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있게 허용할지를 결정하는 것이다. 격리 수준은 크게 READ UNCOMMITED, READ COMMITED, REPEATABLE READ, SERIALIZABLE 4가지로 나뉘는데, "DIRTY READ"라고도 하는 READ UNCOMMITED는 일반적인 데이터베이스에서는 거의 사용하지 않고, SERIALIZABLE 또한 동시성이 중요한 데이터베이스에서는 거의 사용되지 않는다. 4개의 격리 수준에서 순서대로 뒤로 갈수록 각 트랜잭션 간의 데이터 격리(고립)정도가 높아지며, 동시 처리..
InnoDB 스토리지 엔진 아키텍처 1과 InnoDB 스토리지 엔진 아키텍처 2는 여기에서 살펴보실 수 있습니다. Double Write Buffer InnoDB 스토리지 엔진에서는 더티 페이지를 디스크 파일로 플러시할 때, 일부만 기록되는 문제를 막기 위해 Double-Write 기법을 이용한다. 아래 그림은 InnoDB에서 "A" ~ "E"까지의 더티 페이지를 디스크로 플러시하는 상황이다. InnoDB의 스토리지 엔진은 실제 데이터 파일에 변경 내용을 기록하기 전에 "A" ~ "E"까지의 더티 페이지를 우선 묶어서 한 번의 디스크 쓰기로 시스템 테이블스페이스의 DoubleWrite 버퍼에 기록하고, 각 더티 페이지를 파일의 적당한 위치에 하나씩 랜덤으로 쓰기를 실행한다. InnoDB 스토리지 엔진은 ..
MySQL 엔진 아키텍처 MySQL 서버는 크게 MySQL 엔진과 스토리지 엔진으로 구분할 수 있다. MySQL 엔진 MySQL 엔진은 클라이언트로부터의 접속 및 쿼리 요청을 처리하는 커넥션 핸들러와 SQL 파서 및 전처리기, 쿼리의 최적화된 실행을 위한 옵티마이저가 중심을 이룬다. 또한, MySQL은 표준 SQL(ANSI SQL) 문법을 지원하므로 표준 문법에 따라 작성된 쿼리는 타 DBMS와 호환되어 실행될 수 있다. 스토리지 엔진 요청된 SQL 문장을 분석하거나 최적화하는 등 DBMS의 두뇌에 해당하는 처리를 수행하고, 실제 데이터를 디스크 스토리지에 저장하거나 디스크 스토리지로부터 데이터를 읽어온다. MySQL 서버에서 MySQL 엔진은 하나지만 스토리지 엔진은 여러 개를 동시에 사용할 수 있다...
REQUIRES_NEW는 외부 트랜잭션과 내부 트랜잭션을 완전히 분리해서 각각 별도의 물리 트랜잭션을 사용하는 방법이다. 그렇기 때문에 커밋과 롤백도 각각 별도로 이루어지게 된다. 이 방법은 각각 독립된 트랜잭션이기 때문에, 내부 트랜잭션에 문제가 발생해서 롤백 되더라도 기본 설정인 REQUIRED처럼 외부 트랜잭션에는 영향을 주지 않는다. 반대로 외부 트랜잭션에 문제가 발생해도 내부 트랜잭션에 영향을 주진 않는다. 아래 예제를 보면서 작동 원리를 이해해보자! Test Code @Test void inner_rollback_required_new() { log.info("외부 트랜잭션 시작"); TransactionStatus outer = txManager.getTransaction(new Defaul..
- Total
- Today
- Yesterday
- 스프링
- Real MySQL
- 코틀린
- 구현
- 노마드코더
- Spring
- spring boot
- 노마드
- 파이썬
- Refactoring
- 코테
- 북클럽
- 인프런
- MySQL
- 그리디
- 문자열
- Algorithm
- mysql 8.0
- 백준
- 스프링 부트
- 알고리즘
- kotlin
- 정렬
- leetcode
- 데이터베이스
- 김영한
- 자료구조
- 리팩토링
- 릿코드
- webflux
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |