index 9

[DB Optimization#15] HAVING 문 튜닝

SQL에서 집계 함수를 사용할 때 자주 쓰이는 함수가 있습니다. 바로 HAVIN문입니다. 하지만 무분별한 사용은 성능 저하를 초래할 수 있기 때문에, HAVING을 꼭 써야 하는 경우가 아니라면 WHERE문으로 대체하는 것이 더 바람직한 경우가 많습니다. 이번 글에서는 100만 건의 데이터를 기반으로 HAVING을 사용했을 때와 WHERE으로 대체했을 때의 성능 차이를 비교해 보며, 어떤 방식이 더 효율적인지 실습을 통해 확인해 보겠습니다. 실습CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), age INT, department VARCHAR(100), salary INT, created..

SQL 2025.04.17

[DB Optimization#14] WHERE vs ORDER BY, 어디에 인덱스를 거는 것이 좋을까?

SQL 최적화에서 자주 나오는 고민 중 하나는 WHERE 절에 인덱스를 거는 게 좋은지, 아니면 ORDER BY 절에 인덱스를 거는 게 좋은지에 대한 문제입니다. 정답은 하나가 아닙니다. 데이터의 구조, 쿼리의 목적, 그리고 실행 계획에 따라 달라질 수 있기 때문입니다. 이번 글에서는 실제 100만 건의 데이터를 바탕으로 각각의 경우를 비교하고, 어떤 인덱스 전략이 더 효율적인지 실행 시간과 실행 계획을 통해 확인해 보겠습니다. 실습CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), department VARCHAR(100), salary INT, created_at TIMESTAMP DEFAU..

SQL 2025.04.17

[DB Optimization#12] 인덱스가 안 먹히나요?

MySQL에서 인덱스를 걸어도 예상과 달리 EXPLAIN 결과에 Full Table Scan이 찍히는 경우가 있습니다.“인덱스를 걸었는데 왜 작동하지 않지?”라는 의문이 드는 순간, 우리는 쿼리 작성 방식을 돌아봐야 합니다. 이번 글에서는 실제 인덱스를 무력화되는 대표적인 상황을 실습을 통해 알아보고, 어떻게 쿼리를 고쳐야 인덱스를 제대로 활용할 수 있는지 소개합니다. Case 1CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), age INT);SET SESSION cte_max_recursion_depth = 1000000;INSERT INTO users (name, age)WITH RECURSIVE ..

SQL 2025.04.17

[DB Optimization#8] 커버링 인덱스(Covering Index)란?

커버링 인덱스란?MySQL에서 인덱스는 보통 필터링과 정렬을 빠르게 하기 위해 사용됩니다.하지만 인덱스가 하는 일은 거기서 끝나지 않습니다.인덱스만으로도 SQL의 결과를 바로 조회할 수 있다면 훨씬 빠르게 쿼리를 처리할 수 있습니다.이처럼,SQL 실행에 필요한 모든 컬럼이 인덱스에 포함되어 있어, 테이블(데이터 영역)에 접근하지 않아도 되는 인덱스를우리는 커버링 인덱스(Covering Index) 라고 부릅니다. 커버링 인덱스를 왜 쓰는가?간단합니다.인덱스에만 접근하면 되므로 속도가 빠릅니다.테이블 데이터까지 내려가서 가져오는 I/O를 줄일 수 있습니다.결과적으로 디스크 접근량 감소 → 실행 속도 개선으로 이어집니다.예시로 이해해보겠습니다. 아래는 users 테이블입니다. id name create..

SQL 2025.04.17

[DB Optimization#7] 멀티 컬럼 인덱스(Multiple-Column Index)란?

멀티 컬럼 인덱스란?멀티 컬럼 인덱스란, 2개 이상의 컬럼을 묶어서 만든 인덱스를 말합니다.즉, 단일 컬럼이 아니라 두 개 이상의 컬럼을 기준으로 정렬된 탐색용 자료구조라고 이해하면 됩니다.보다 직관적으로 표현하자면,여러 컬럼을 기준으로 데이터를 미리 정렬해놓은 표가 멀티 컬럼 인덱스입니다. CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, 이름 VARCHAR(100), 부서 VARCHAR(100), 나이 INT);INSERT INTO users (이름, 부서, 나이) VALUES('박미나', '회계', 26),('김미현', '회계', 23),('김민재', '회계', 21),('이재현', '운영', 24),('조민규', '운영', 2..

SQL 2025.04.17

[DB Optimization#6] 인덱스를 많이 걸면 정말 느려질까?

SQL 인덱스는 조회 성능을 높여주는 강력한 도구입니다.그래서 많은 분들이 이렇게 생각하곤 합니다."그럼 자주 사용할 만한 컬럼엔 전부 인덱스를 걸면 되는 거 아냐?"하지만 현실은 다릅니다.인덱스는 조회 성능을 높여주는 대신, 쓰기 작업(삽입, 수정, 삭제) 성능을 떨어뜨립니다. 인덱스가 많아지면 성능이 왜 느려질까?인덱스를 생성한다는 것은 단순히 "검색이 빨라진다"는 의미가 아닙니다.인덱스를 위한 내부 자료 구조(B-tree)가 함께 관리되기 때문에, 데이터를 삽입하거나 수정할 때마다 MySQL은 원본 테이블뿐만 아니라 인덱스 테이블까지 함께 갱신해야 합니다. 즉, 인덱스의 개수가 많을수록 쓰기 작업 시 처리해야 할 작업량도 늘어나게 되는 것입니다. 실제로 인덱스가 없는 테이블과 인덱스가 많은 테이블 ..

SQL 2025.04.17

[DB Optimization#5] UNIQUE

MySQL에서 인덱스는 단순히 검색 성능을 높이기 위한 도구일 뿐만 아니라, 데이터의 무결성을 보장하는 제약 조건과도 밀접하게 연결되어 있습니다. 이번 글에서는 UNIQUE 제약 조건을 지정했을 때, MySQL이 자동으로 인덱스를 생성하는 동작 방식과 그 특징을 살펴보겠습니다. UNIQUE 제약 조건이란?UNIQUE 제약 조건은 해당 컬럼에 중복된 값이 들어가지 못하도록 제한하는 기능입니다.예를 들어, 회원의 email이나 username은 보통 중복을 허용하지 않기 때문에 UNIQUE 제약 조건을 걸어둡니다. 그런데 이 UNIQUE 제약 조건은 단순히 데이터 중복만 막아주는 것이 아닙니다.자동으로 인덱스까지 생성하여, 검색 성능 또한 개선해 줍니다. 실제 코드로 확인해보겠습니다. users라는 테이블..

SQL 2025.04.17

[DB Optimization#3] 인덱스(Index)란?

DB 성능을 높이기 위한 가장 대표적인 방법 중 하나는 인덱스(index) 를 활용하는 것입니다.많은 튜닝 기법이 존재하지만, 인덱스는 그 중에서도 기본이자 핵심입니다.이번 글에서는 인덱스가 무엇인지, 왜 필요한지, 어떻게 작동하는지를 예시를 통해 알아보겠습니다. 인덱스(Index)란?데이터베이스에서 인덱스는 검색 속도를 향상시키기 위한 자료 구조입니다.이는 데이터를 보다 빠르게 조회할 수 있도록 설계된 메커니즘입니다. 조금 더 직관적으로 말하자면, 인덱스는 특정 컬럼을 기준으로 데이터를 미리 정리해 둔 ‘찾기 쉬운 목록’이라고 이해하면 됩니다.마치 책의 목차처럼, 원하는 정보를 빠르게 찾아갈 수 있도록 돕는 역할을 합니다. 예를 들어 아래와 같은 users 테이블이 있다고 가정해봅시다. id n..

SQL 2025.04.16

[DB Optimization#2] MySQL 구조

개발을 하다 보면 어느 순간부터 데이터베이스가 느려졌다는 이야기를 듣게 됩니다.특히 서비스가 실제 사용자에게 제공되는 시점이 되면 SQL 응답 속도가 체감될 정도로 느려지는 현상을 마주하게 됩니다.이럴 때 무작정 쿼리를 수정하기보다 먼저 해야 할 일은, MySQL 내부 구조를 이해하는 것입니다. MySQL 구조를 왜 알아야 할까?SQL이 어떻게 실행되고, 어떤 과정에서 성능 병목이 발생하는지 이해하지 못하면문제의 원인을 파악하기도 어렵고, 제대로 된 튜닝도 할 수 없습니다.MySQL의 구조를 이해하면 다음과 같은 질문에 답할 수 있습니다.어떤 단계에서 성능 저하가 발생하는가?어떤 요인이 병목을 유발하는가?SQL 튜닝은 어떤 지점을 개선해야 하는가? MySQL 아키텍처 개요 MySQL에서 하나의 SQ..

SQL 2025.04.16