MySQL 서버는 사용자의 요청을 처리하기 위해 1) 데이터를 가공하는 기본 절차 2) 빠른 성능을 보장하기 위한 최적화를 수행합니다. 이번 글에서는 데이터를 정렬하거나 그루핑하는 등의 기본 데이터 가공 기능에 관해 살펴보겠습니다. 풀 테이블 스캔과 풀 인덱스 스캔 풀 테이블 스캔은 인덱스를 사용하지 않고 테이블의 데이터를 처음부터 끝까지 읽는 작업을 의미합니다. 다음과 같은 조건일 때 주로 풀 테이블 스캔을 선택합니다. 테이블의 레코드 건수가 너무 작아 인덱스를 사용하는 것보다 테이블을 스캔하는 것이 빠를 경우(일반적으로 테이블이 페이지 1개로 구성된 경우) WHERE 절이나 ON 절에 인덱스를 이용할 수 있는 적절한 조건이 없는 경우 인덱스 레인지 스캔을 사용할 수 있는 쿼리라고 하더라도 옵티마이저가..
MySQL 서버로 요청된 쿼리는 결과는 동일하지만 내부적인 방법은 다양합니다. 다양한 방법 중 어떤 방법이 최적이고 최소 비용이 소모될지 결정해야 합니다. MySQL은 쿼리를 최적으로 실행하기 위해 테이블의 데이터 통계 정보를 참조하여 최적의 실행 계획을 수립합니다. 이러한 기능은 옵티마이저가 수행합니다. 쿼리 수행 절차 MySQL 서버에서 쿼리가 실행되는 과정은 크게 세 단계로 나눌 수 있습니다. SQL 문장을 쪼개서 MySQL 서버가 이해할 수 있는 수준으로 분리 SQL 파싱 정보를 확인하면서 어떤 테이블을 읽고 어떤 인덱스를 사용할지 선택 테이블 읽기 순서나 선택된 인덱스를 이용해 스토리지 엔진으로부터 데이터를 가져옴 첫 번째 단계를 "SQL 파싱"이라 하며, SQL 파서가 실행합니다. 이 단계에서..
외래키는 InnoDB 스토리지 엔진에만 생성할 수 있습니다. 외래키 제약이 설정되면 자동으로 연관된 테이블의 칼럼에 인덱스까지 생성됩니다. 외래키가 제거되지 않은 상태에서 자동으로 생성된 인덱스를 삭제할 수 없습니다. 특징 InnoDB의 외래키에는 두 가지 중요한 특징이 있습니다. 테이블의 변경(쓰기 잠금)이 발생하는 경우에만 잠금 경합이 발생한다. 외래키와 연관되지 않은 칼럼의 변경은 최대한 잠금 경합을 발생시키지 않는다. 다음과 같은 테이블이 있습니다. mysql> CREATE TABLE parent ( id INT NOT NULL fd VARCHAR(100) NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB; mysql> CREATE TABLE child ( id INT ..
유니크 인덱스란 유니크는 인덱스라기 보다는 제약 조건에 가깝습니다. 테이블이나 인덱스에 같은 값이 2개 이상 저장될 수 없음을 의미하는데, MySQL에서는 인덱스 없이 유니크 제약만을 설정할 수 없습니다. 유니크 인덱스에는 NULL도 저장될 수 있습니다. NULL은 특정 값이 아니므로 2개 이상 저장될 수 있습니다. 유니크 인덱스와 일반 세컨더리 인덱스의 비교 유니크 인덱스와 일반 세컨더리 인덱스는 구조상 동일하고 유니크 제약 조건의 유무만 다릅니다. 인덱스 읽기 두 인덱스의 구조가 동일하기 때문에 동일한 레코드양을 읽는다면 성능차이는 없습니다. 다만 일반 인덱스는 키 값의 중복이 없기 때문에 읽어야할 값이 더 많을 수 있습니다. 레코드 1건을 검색하는 경우 두 인덱스의 실행 계획에 차이가 있습니다. 하..
개요 MySQL의 InnoDB 스토리지 엔진은 PK에 대해 클러스터링 인덱스를 자동으로 생성합니다. 그렇다면 클러스터링 인덱스 무엇이길래 테이블마다 존재하는 것일까요? 이 글에서 알아봅시다. 클러스터링 인덱스 클러스터링이란 여러 개를 하나로 묶는다는 의미로 사용됩니다. 클러스터링 인덱스도 이러한 의미에서 크게 벗어나지 않습니다. InnoDB에서 클러스터링은 테이블의 레코드를 비슷한 것들끼리(PK 기준) 묶어서 저장하는 형태로 구현됩니다. 이는 주로 비슷한 값들을 동시에 조회하는 경우가 많다는 점에서 착안한 것입니다. 클러스터링 인덱스는 PK에 대해서만 적용됩니다. PK값이 비슷한 레코드끼리 묶어서 저장됩니다. 즉, PK 값에 의해 레코드의 저장 위치가 결정된다는 것입니다. 또한 PK 값이 변경된다면 레코..
칼럼의 값을 변형해서 만들어진 값에 대해 인덱스를 구축할 수 있습니다. MySQL 서버에서 함수 기반 인덱스를 구현하는 방법은 다음과 같습니다. 1. 가상 칼럼을 이용한 인덱스 2. 함수를 이용한 인덱스 함수 기반 인덱스는 인덱싱할 값을 계산하는 과정의 차이만 존재합니다. 가상 칼럼을 이용한 인덱스 다음과 같은 테이블이 있습니다. mysql> CREATE TABLE user( user_id BIG_INT first_name VARCHAR(10), last_name VARCHAR(10), PRIMARY KEY (user_id) ); first_name와 last_name을 합쳐서 검색해야 하는 요건이 생겼습니다. 두 칼럼을 합친 full_name이라는 칼럼을 만들어 인덱스를 생성해도 되지만 다른 방법이 있..
이전 글에 이어서 MySQL의 B-Tree 인덱스에 대해 알아보겠습니다. [MySQL] B-Tree 인덱스 - 1 대표적인 인덱스인 B-Tree 인덱스를 MySQL의 관점에서 알아봅시다. 구조 Tree는 루트 노드와 리프 노드 그 사이에 브랜치 노드로 이루어져 있습니다. 그중 리프 노드에 데이터 레코드의 주솟값을 저 acisliver.tistory.com [MySQL] B-Tree 인덱스 - 2 이전 글에 이어서 B-Tree 인덱스를 MySQL 관점에서 살펴보겠습니다. [MySQL] B-Tree 인덱스 - 1 대표적인 인덱스인 B-Tree 인덱스를 MySQL의 관점에서 알아봅시다. 구조 Tree는 루트 노드와 리프 노드 그 사이 acisliver.tistory.com [MySQL] B-Tree 인덱스 -..
이전 글에 이어서 MySQL의 B-Tree 인덱스에 대해 알아보겠습니다. [MySQL] B-Tree 인덱스 - 1 대표적인 인덱스인 B-Tree 인덱스를 MySQL의 관점에서 알아봅시다. 구조 Tree는 루트 노드와 리프 노드 그 사이에 브랜치 노드로 이루어져 있습니다. 그중 리프 노드에 데이터 레코드의 주솟값을 저 acisliver.tistory.com [MySQL] B-Tree 인덱스 - 2 이전 글에 이어서 B-Tree 인덱스를 MySQL 관점에서 살펴보겠습니다. [MySQL] B-Tree 인덱스 - 1 대표적인 인덱스인 B-Tree 인덱스를 MySQL의 관점에서 알아봅시다. 구조 Tree는 루트 노드와 리프 노드 그 사이 acisliver.tistory.com B-Tree 인덱스의 정렬 및 스캔 ..