개발/Go

[Gin] GORM 성능 최적화 팁 - Preload, Select, Index 전략까지!

devhooney 2025. 6. 4. 08:48
728x90

GORM은 Go에서 가장 널리 쓰이는 ORM이지만, 아무 설정 없이 쓰다 보면 쿼리가 많아지고 성능이 떨어질 수 있다.
이번 글에서는 GORM에서 성능을 높이기 위한 Preload, Select, Index 전략들을 정리해보자.

 


 

📌 목차
- N+1 문제와 Preload
- 필요한 컬럼만 조회하기 — Select
- Index 전략
- 정리

 

 

 

 

 

728x90

 

 

1. N+1 문제와 Preload

 

🤔 N+1 문제란?
예를 들어 게시글(Post)과 작성자(User) 관계가 있을 때, 게시글 10개를 조회하면서 각 게시글의 작성자를 따로 조회하면 1 + N 쿼리가 발생한다.

 

 

 

type Post struct {
	ID     uint
	Title  string
	UserID uint
	User   User
}
// 잘못된 예 (N+1 문제 발생)
var posts []Post
db.Find(&posts) // 1번 쿼리
for _, post := range posts {
    db.Model(&post).Association("User").Find(&post.User) // N번 쿼리
}

 

✅ 해결: Preload 사용

// Preload 사용 (1번의 조인 쿼리로 해결)
db.Preload("User").Find(&posts)

 

- GORM은 내부적으로 LEFT JOIN이 아닌 별도의 SELECT 쿼리로 Preload를 실행함
- 관계 이름이 정확히 일치해야 한다 (User vs user 구분)

 

⛏️ 조건부 Preload

db.Preload("User", "role = ?", "admin").Find(&posts)

 

 

 

 

 

 

2. 필요한 컬럼만 조회하기 - Select


GORM 기본 설정은 SELECT *로 모든 컬럼을 조회한다.
하지만 실무에서는 정말 필요한 필드만 조회하는 게 훨씬 빠르고 가볍다.

 

🎯 기본 사용

db.Select("id", "name").Find(&users)

 

🧩 Struct도 가능

type SlimUser struct {
	ID   uint
	Name string
}

var users []SlimUser
db.Model(&User{}).Select("id", "name").Scan(&users)

 

🚫 Tip: Preload + Select는 주의
Preload된 모델에는 Select 옵션이 적용되지 않음.
따라서 하위 모델에 대해서도 Select 제어가 필요하면 Joins() 등을 사용해야 함.

 

 

 

 

 

3. Index 전략

GORM은 마이그레이션 시 인덱스를 자동 생성할 수 있고, 조회 성능 향상에 매우 중요하다.

 

🔧 단일 필드 인덱스

type User struct {
	ID    uint
	Email string `gorm:"index"` // index 생성
}

 

🧱 복합 인덱스

type Order struct {
	UserID    uint `gorm:"index:idx_user_product"`
	ProductID uint `gorm:"index:idx_user_product"`
}

 

- idx_user_product라는 이름의 복합 인덱스 생성됨
- 조건이 정확히 맞지 않으면 인덱스가 잘 안 쓰이므로 쿼리 구조도 중요

 

🔍 유니크 인덱스

Username string `gorm:"uniqueIndex"`

 

⚠️ 주의: 자동 마이그레이션은 인덱스를 변경하지 않음
기존 인덱스가 있으면 자동으로 수정되지 않으므로, 필요시 수동으로 DROP INDEX 후 재생성 필요

 

 

 

 

🧠 정리

전략 핵심 내용
Preload N+1 문제 해결, 연관 모델 미리 로드
Select 필요한 컬럼만 조회해서 속도와 메모리 절약
Index 조회 성능 향상, 조건에 맞는 인덱스 설계 중요

 

 

 

 

 

728x90