웹 개발
데이터베이스 인덱스가 없거나 제대로 안 탈 때
쿼리가 느려지거나 데이터를 못 찾을 때, 인덱스 문제가 원인인지 빠르게 진단하는 방법을 정리했다.
쿼리가 갑자기 느려지거나, 조인 성능이 떨어지는 경우가 많다. 데이터가 몇 천 건일 때는 눈에 띄지 않지만, 몇 백만 건이 되면 인덱스의 유무가 생사를 가른다.
Prisma에서 마이그레이션 상태 확인
먼저 현재 스키마와 데이터베이스의 상태가 일치하는지 본다.
npx prisma validate
npx prisma migrate status
npx prisma migrate reset # 데이터가 없으면
마이그레이션이 pending 상태면, 인덱스를 포함한 스키마 변경이 아직 적용되지 않은 것이다.
실제 데이터베이스에서 인덱스 목록 보기
PostgreSQL 기준:
-- 모든 인덱스 조회
\d table_name
-- 더 자세한 정보
SELECT
indexname,
indexdef
FROM pg_indexes
WHERE tablename = 'users';
MySQL이면:
SHOW INDEXES FROM table_name;
Prisma 스키마에 @@index 디렉티브가 있어도, 마이그레이션이 실행되지 않았으면 실제로는 없다.
쿼리 실행 계획으로 인덱스 사용 확인
인덱스가 있어도, 쿼리 최적화기가 사용하지 않을 수 있다.
EXPLAIN ANALYZE SELECT * FROM users WHERE email = '[email protected]';
결과에서:
Seq Scan: 전체 테이블 스캔 (인덱스 미사용)Index Scan: 인덱스를 탔다rows: 실제 조회 행 수actual time: 실제 실행 시간
데이터가 적으면, PostgreSQL이 전체 테이블을 스캔하는 게 더 빠르다고 판단할 수 있다. 이 경우 데이터가 많아질 때까지는 인덱스가 필요 없을 수도 있다.
Prisma 스키마에서 인덱스 정의 확인
model User {
id Int @id @default(autoincrement())
email String @unique // 고유 인덱스 자동 생성
name String
@@index([name]) // 복합 인덱스
@@index([email, createdAt])
}
@unique는 자동으로 인덱스를 만들고, @@index는 명시적으로 지정할 수 있다.
마이그레이션 파일 검사
생성된 마이그레이션 파일을 직접 본다.
ls prisma/migrations/
cat prisma/migrations/*/migration.sql
CREATE INDEX 구문이 실제로 있는지 확인한다. 없다면 Prisma 스키마의 인덱스 정의가 마이그레이션에 반영되지 않은 것이다.
성능 영향 측정
인덱스를 추가한 후, 실제로 쿼리가 빨라지는지 확인한다.
# 마이그레이션 적용
npx prisma migrate deploy
# 테스트 쿼리 실행 (시간 측정)
time npx prisma studio # 또는 직접 쿼리 실행
쿼리 시간이 ms 단위에서 변한다면, 인덱스가 제대로 작동하는 것이다.
다중 컬럼 인덱스의 순서 중요
@@index([userId, createdAt])
이 인덱스는 WHERE userId = 1 AND createdAt > now() 쿼리에는 효과적이지만, WHERE createdAt > now() 만으로는 인덱스를 제대로 탈 수 없다. 쿼리 패턴에 맞춰 인덱스 컬럼 순서를 설계해야 한다.