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 10:02 AM
isPublic
isPublic
series
비전공자도 이해할 수 있는 MySQL 성능 최적화 입문/실전 (SQL 튜닝편)
slug
what-causes-when-creating-too-many-index
type
post
updatedAt
Mar 24, 2026 09:00
인덱스를 사용하면 데이터를 조회할 때의 성능이 향상된다. 그러면 인덱스를 무조건적으로 많이 추가하는 게 좋다고 착각할 수도 있다. 하지만 인덱스를 추가하면 조회 성능은 올라가지만, 쓰기 작업(삽입, 수정, 삭제)의 성능은 저하된다.
 
왜 그런 지 직관적으로 먼저 이해해보자.
notion image
인덱스를 추가한다는 건 인덱스용 테이블이 추가적으로 생성된다는 뜻이다. 그렇다면 인덱스를 추가하지 않은 상태에서 원래 테이블에만 데이터를 넣는 것보다, 인덱스를 추가한 상태에서 원래 테이블과 인덱스용 테이블 둘 다에 데이터를 넣어야 하는 게 더 느릴 수 밖에 없다. 인덱스의 개수가 많아지면 많아질수록 성능은 느려질 수 밖에 없다. 데이터를 삽입하는 것 이외에도 수정, 삭제 작업에서도 같은 이유로 성능이 느려진다.
 
 
실제로도 그런지 테스트해보자.
  1. 테이블 생성하기
    1. -- 테이블 A: 인덱스가 없는 테이블 CREATE TABLE test_table_no_index ( id INT AUTO_INCREMENT PRIMARY KEY, column1 INT, column2 INT, column3 INT, column4 INT, column5 INT, column6 INT, column7 INT, column8 INT, column9 INT, column10 INT ); -- 테이블 B: 인덱스가 많은 테이블 CREATE TABLE test_table_many_indexes ( id INT AUTO_INCREMENT PRIMARY KEY, column1 INT, column2 INT, column3 INT, column4 INT, column5 INT, column6 INT, column7 INT, column8 INT, column9 INT, column10 INT );
 
  1. 인덱스 추가
    1. -- 각 컬럼에 인덱스를 추가 CREATE INDEX idx_column1 ON test_table_many_indexes (column1); CREATE INDEX idx_column2 ON test_table_many_indexes (column2); CREATE INDEX idx_column3 ON test_table_many_indexes (column3); CREATE INDEX idx_column4 ON test_table_many_indexes (column4); CREATE INDEX idx_column5 ON test_table_many_indexes (column5); CREATE INDEX idx_column6 ON test_table_many_indexes (column6); CREATE INDEX idx_column7 ON test_table_many_indexes (column7); CREATE INDEX idx_column8 ON test_table_many_indexes (column8); CREATE INDEX idx_column9 ON test_table_many_indexes (column9); CREATE INDEX idx_column10 ON test_table_many_indexes (column10);
 
  1. 데이터 삽입 성능 테스트
    1. -- 높은 재귀(반복) 횟수를 허용하도록 설정 -- (아래에서 생성할 더미 데이터의 개수와 맞춰서 작성하면 된다.) SET SESSION cte_max_recursion_depth = 100000; -- 인덱스가 없는 테이블에 데이터 10만개 삽입 INSERT INTO test_table_no_index (column1, column2, column3, column4, column5, column6, column7, column8, column9, column10) WITH RECURSIVE cte AS ( SELECT 1 AS n UNION ALL SELECT n + 1 FROM cte WHERE n < 100000 ) SELECT FLOOR(RAND() * 1000), FLOOR(RAND() * 1000), FLOOR(RAND() * 1000), FLOOR(RAND() * 1000), FLOOR(RAND() * 1000), FLOOR(RAND() * 1000), FLOOR(RAND() * 1000), FLOOR(RAND() * 1000), FLOOR(RAND() * 1000), FLOOR(RAND() * 1000) FROM cte; -- 인덱스가 많은 테이블에 데이터 10만개 삽입 INSERT INTO test_table_many_indexes (column1, column2, column3, column4, column5, column6, column7, column8, column9, column10) WITH RECURSIVE cte AS ( SELECT 1 AS n UNION ALL SELECT n + 1 FROM cte WHERE n < 100000 ) SELECT FLOOR(RAND() * 1000), FLOOR(RAND() * 1000), FLOOR(RAND() * 1000), FLOOR(RAND() * 1000), FLOOR(RAND() * 1000), FLOOR(RAND() * 1000), FLOOR(RAND() * 1000), FLOOR(RAND() * 1000), FLOOR(RAND() * 1000), FLOOR(RAND() * 1000) FROM cte;
       
      [인덱스를 생성하지 않은 테이블에 10만개 데이터 삽입 시 걸리는 속도]
      notion image
      약 300ms 정도의 시간이 소요된다.
       
      [인덱스를 많이 생성한 테이블에 10만개 데이터 삽입 시 걸리는 속도]
      notion image
      약 2000ms로 시작해서 25,000ms까지 걸리는 걸 확인할 수 있다. 데이터가 많아지면 많아질수록 점점 삽입 속도가 느려지는 걸 확인할 수 있다.
       
⭐
[이것만은 꼭 기억해두자!] - 최소한의 인덱스만 사용하려고 하자. - 인덱스를 추가하면 조회 속도는 빨라지나, 쓰기(삽입, 수정, 삭제) 속도는 느려짐을 항상 기억하자.
📎
이 글은 비전공자도 이해할 수 있는 MySQL 성능 최적화 입문/실전 (SQL 튜닝편) 강의의 수업 자료 중 일부입니다.