인덱스(Index)는 데이터베이스에서 테이블의 데이터 검색 속도를 향상시키기 위해 사용되는 특수한 데이터 구조. 마치 책의 색인처럼 특정 데이터의 위치를 빠르게 찾을 수 있도록 도와주는 역할.
인덱스를 사용하는 이유
인덱스의 단점
-- 고객 테이블에 인덱스 생성
CREATE INDEX idx_customer_name ON Customers(Name);
-- 인덱스를 사용한 검색
SELECT *
FROM Customers
WHERE Name = 'John Doe';
인덱스의 종류
인덱스(Index)는 데이터 검색 속도를 향상시키기 위한 핵심적인 데이터베이스 최적화 도구입니다. 신입 개발자나 취준생 입장에서 이를 학습하고 실습하려면, 이론과 실습을 병행하여 인덱스의 필요성을 이해하고, 실제 프로젝트에서 어떻게 활용하는지 익히는 것이 중요합니다.
Full Table Scan의 성능 문제를 체험.SQL 스크립트
CREATE TABLE Products (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
description TEXT,
price DECIMAL(10, 2),
category VARCHAR(255)
);
-- 대량 데이터 삽입 (10만 건)
INSERT INTO Products (name, description, price, category)
SELECT CONCAT('Product', FLOOR(RAND() * 100000)), 'Sample description', RAND() * 100, 'Category'
FROM information_schema.tables t1, information_schema.tables t2
LIMIT 100000;
-- 검색 쿼리 실행 시간 확인
EXPLAIN SELECT * FROM Products WHERE name = 'Product12345';
결과
EXPLAIN 명령어로 Full Table Scan 확인.SQL 스크립트
-- 인덱스 생성
CREATE INDEX idx_name ON Products(name);
-- 검색 쿼리 실행
EXPLAIN SELECT * FROM Products WHERE name = 'Product12345';
결과
EXPLAIN 결과에 인덱스 사용이 표시됨.Entity 코드
import jakarta.persistence.*;
@Entity
@Table(name = "products", indexes = {
@Index(name = "idx_name", columnList = "name")
})
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
private String description;
private Double price;
private String category;
// Getters and Setters
}
Repository 코드
import org.springframework.data.jpa.repository.JpaRepository;
public interface ProductRepository extends JpaRepository<Product, Long> {
List<Product> findByName(String name);
}
Test 코드
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.junit.jupiter.api.Test;
@SpringBootTest
public class ProductIndexTest {
@Autowired
private ProductRepository productRepository;
@Test
public void testSearchWithIndex() {
long startTime = System.currentTimeMillis();
productRepository.findByName("Product12345");
long endTime = System.currentTimeMillis();
System.out.println("Search Time: " + (endTime - startTime) + "ms");
}
}
결과
SQL 스크립트
-- 대량 데이터 삽입
INSERT INTO Products (name, description, price, category)
SELECT CONCAT('NewProduct', FLOOR(RAND() * 100000)), 'Description', RAND() * 100, 'NewCategory'
FROM information_schema.tables t1, information_schema.tables t2
LIMIT 50000;
-- 대량 데이터 업데이트
UPDATE Products SET category = 'UpdatedCategory' WHERE category = 'NewCategory';
결과
SQL 스크립트
-- 복합 인덱스 생성
CREATE INDEX idx_name_category ON Products(name, category);
-- 복합 조건 검색
EXPLAIN SELECT * FROM Products WHERE name = 'Product12345' AND category = 'Category';
결과
커버링 인덱스(Covering Index) 실습
특정 조회 쿼리에서 인덱스만으로 필요한 데이터를 처리하도록 설정.
클러스터형 vs 비클러스터형 인덱스 실습
MySQL의 InnoDB 클러스터형 인덱스와 비교해 보기.
인덱스 조정
인덱스가 과도하게 설정된 경우 성능 저하를 시뮬레이션하고 최적화 방법 학습.
Spring Cache와 연동
인덱스를 사용한 쿼리를 캐싱해 성능 최적화를 테스트.
인덱스 실습은 단순한 이론 학습을 넘어, 실질적인 검색 성능 최적화와 DML 작업 성능 변화를 이해하는 데 도움이 됩니다. 이러한 실습을 통해 백엔드 개발자로서 데이터베이스 성능 최적화 역량을 강화할 수 있습니다.