JSCODE Logo
JSCODE 박재성JSCODE 제이온JSCODE 시니
과외유튜브블로그후기
완강 후기 이벤트블로그 리뷰 이벤트AWS SAA 합격 후기 이벤트
회사명 : JSCODE대표 : 박재성사업자 등록번호 : 244-22-01557통신판매업 : 제 2023-인천미추홀-0381 호

서울특별시 구로구 경인로 20가길 11(오류동, 아델리아)

Copyright ⓒ 2026 JSCODE - 최상위 현업 개발자들의 프로그래밍 교육 All rights reserved.

이용약관개인정보처리방침

비전공자도 이해할 수 있는 MySQL 성능 최적화 입문/실전 (SQL 튜닝편)

MySQL 성능 최적화를 본격적으로 배우기 전에!

신입 백엔드 면접에서 자주 물어보는 ‘DB 성능 최적화’ 경험?!
DB 성능 개선할 때 ‘SQL 튜닝’을 가장 먼저 해야 하는 이유 (vs 스케일업, 레플리케이션, 샤딩, 캐싱)
성능 개선을 위한 MySQL 구조 파악 / SQL 튜닝의 핵심

인덱스(Index) 기본 개념 / 실전 활용법

인덱스(Index)란?
[실습] 인덱스 직접 설정해보기 / 성능 측정해보기
기본으로 설정되는 인덱스 (PK)
제약 조건을 추가하면 자동으로 생성되는 인덱스 (UNIQUE)
[실습] 인덱스를 무식하게 많이 걸면 어떻게 될까?
멀티 컬럼 인덱스 (Mulitple-Column Index)란?
[실습] 멀티 컬럼 인덱스 직접 설정해보기 / 작동방식 이해하기
멀티 컬럼 인덱스 생성 시 주의점
커버링 인덱스(Covering Index)란?

실행 계획(EXPLAIN)을 활용해 성능 저하 요인 찾아내기

SQL문의 ‘실행 계획’ 사용해보기 (EXPLAIN)
실행 계획에서 type 의미 분석하기 (ALL, index)
실행 계획에서 type 의미 분석하기 (const, range, ref)

SQL문 튜닝 연습하기

[실습] 한 번에 너무 많은 데이터를 조회하는 SQL문 튜닝하기
[실습] WHERE문이 사용된 SQL문 튜닝하기 - 1
[실습] WHERE문이 사용된 SQL문 튜닝하기 - 2
[실습] 인덱스를 걸었는데도 인덱스가 작동하지 않는 경우 - 1
[실습] 인덱스를 걸었는데도 인덱스가 작동하지 않는 경우 - 2
[실습] ORDER BY문이 사용된 SQL문 튜닝하기
[실습] WHERE문에 인덱스를 걸기 vs ORDER BY문에 인덱스를 걸기
[실습] HAVING문이 사용된 SQL문 튜닝하기

실전 SQL문으로 튜닝 직접 해보기

[실습] 유저 이름으로 특정 기간에 작성된 글 검색하는 SQL문 튜닝하기
[실습] 특정 부서에서 최대 연봉을 가진 사용자들 조회하는 SQL문 튜닝하기
[실습] 부서별 최대 연봉을 가진 사용자들 조회하는 SQL문 튜닝하기
[실습] 2023년 주문 데이터 조회하는 SQL문 튜닝하기
[실습] 2024년 1학기 평균 성적이 100점인 학생 조회하는 SQL문 튜닝하기
[실습] 좋아요 많은 순으로 게시글 조회하는 SQL문 튜닝하기
← 블로그 목록으로 돌아가기

[실습] 인덱스 직접 설정해보기 / 성능 측정해보기

JSCODE 박재성
JSCODE 박재성
2026. 03. 24.
author
JSCODE 박재성
category
MySQL
createdAt
Dec 2, 2025 07:02 PM
isPublic
isPublic
series
비전공자도 이해할 수 있는 MySQL 성능 최적화 입문/실전 (SQL 튜닝편)
slug
create-index-and-measure-performance
type
post
updatedAt
Mar 24, 2026 09:00

✅ 인덱스 직접 설정해보기 / 성능 측정하고 비교해보기

아래의 구성과 동일하게 테이블을 셋팅해보고, 인덱스를 설정해보자.
notion image
 
  1. 테이블 생성
    1. DROP TABLE IF EXISTS users; # 기존 테이블 삭제 CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), age INT );
 
 
  1. 100만 건의 랜덤 데이터 삽입
    1. 인덱스 설정 전후의 성능 차이를 비교하기 위해 랜덤 데이터를 넣어보자.
      -- 높은 재귀(반복) 횟수를 허용하도록 설정 -- (아래에서 생성할 더미 데이터의 개수와 맞춰서 작성하면 된다.) SET SESSION cte_max_recursion_depth = 1000000; -- 더미 데이터 삽입 쿼리 INSERT INTO users (name, age) WITH RECURSIVE cte (n) AS ( SELECT 1 UNION ALL SELECT n + 1 FROM cte WHERE n < 1000000 -- 생성하고 싶은 더미 데이터의 개수 ) SELECT CONCAT('User', LPAD(n, 7, '0')), -- 'User' 다음에 7자리 숫자로 구성된 이름 생성 FLOOR(1 + RAND() * 1000) AS age -- 1부터 1000 사이의 랜덤 값으로 나이 생성 FROM cte; -- 잘 생성됐는 지 확인 SELECT COUNT(*) FROM users;
      • 참고) 이 SQL문을 스스로 작성할 수 있을 정도까지는 공부하지 않아도 된다. 위 SQL문을 내 테이블과 컬럼에 맞게 커스텀 할 수 있을 정도까지만 이해하고 있으면 된다.
       
       
  1. 데이터 조회해보기
    1. SELECT * FROM users WHERE age = 23;
      • 주의) Workbench, DBeaver와 같은 GUI 툴을 써서 위 쿼리문을 날릴 경우, 데이터의 개수가 제한돼서 조회된다. 해당 프로그램에 자체적으로 limit가 걸려있는 지 체크해보기 바란다.
        • DBeaver에서는 한 번에 조회할 수 있는 데이터 개수가 200개로 제한이 걸려있다. 이 제한이 걸려있으면 제대로 성능 테스트를 하기가 어렵다.
          DBeaver에서는 한 번에 조회할 수 있는 데이터 개수가 200개로 제한이 걸려있다. 이 제한이 걸려있으면 제대로 성능 테스트를 하기가 어렵다.
           
           
  1. SQL문 실행 시 걸리는 소요 시간 측정하기
    1. ❗
      성능 개선을 할 때 ‘빨라진 것 같아요'라는 말은 없다. 수치를 정확히 측정해서 얼마나 더 빨라지고 느려졌는 지를 정확하게 숫자로 얘기할 수 있어야 한다.
      데이터 조회를 할 때 걸리는 소요 시간이 대략 200ms 정도 걸린다.
      notion image
 
 
  1. 인덱스 설정하기
    1. 인덱스 생성
      # 인덱스 생성 # CREATE INDEX 인덱스명 ON 테이블명 (컬럼명); CREATE INDEX idx_age ON users(age);
       
      인덱스 조회
      # SHOW INDEX FROM 테이블명; SHOW INDEX FROM users;
 
 
  1. 데이터 다시 조회해보고 SQL문 실행 소요 시간 측정해보기
    1. SELECT * FROM users WHERE age = 23;
      데이터 조회를 해보니 약 40ms 정도 걸린다.
      notion image
      인덱스를 적용 전과 후의 성능 차이가 200ms → 40ms로 5배 정도 차이가 난다.
 
 

✅ 직관적으로 이해하기

notion image
인덱스를 직접 생성하게 되면 우리 눈에는 안 보이지만 왼쪽과 같은 표가 시스템 내부적으로 생성된다. 나이를 기준으로 정렬해놓은 표를 가지고 있기 때문에, 나이를 기준으로 데이터를 조회할 때 훨씬 빠르게 찾을 수 있었던 것이다.
 
📎
이 글은 비전공자도 이해할 수 있는 MySQL 성능 최적화 입문/실전 (SQL 튜닝편) 강의의 수업 자료 중 일부입니다.