UUID PK, 진짜 느릴까? BIGINT와 성능 차이 정리

2025. 12. 18. 01:28·PostgreSQL

PK의 타입에 따른 비용에 대한 생각

예전에 한 프로젝트에서 PK를 UUID 문자열로 사용한 적이 있었다. 설계 리뷰를 하던 중 한 팀원이 이런 말을 했던 게 아직도 기억난다. "PK를 문자열로 두면, 정수랑 비교할 때 코스트가 더 크지 않나요?" 그때 든 생각이 어차피 "인덱스 타니까 괜찮지 않을까?" "요즘 서비스들 다 UUID 쓰던데?" 라는 생각으로 넘어갔다. 그리고 작은 프로젝트라서 큰 문제가 있지는 않았지만 프로젝트를 진행하면서 알게 됐다. 이 질문은 단순히 문자열 vs 정수 비교 비용에 대한 이야기가 아니라, DB 인덱스 구조, 데이터 저장 방식, 그리고 성능 전반에 대한 문제라는 것을. PK는 단순한 식별자가 아니다. DB 입장에서 PK는 가장 중요한 인덱스이며, 어떤 타입을 선택하느냐에 따라 INSERT 성능, 조회 성능, 메모리 사용량까지 전부 달라진다. 특히 UUID를 문자열로 저장할 경우, 정수형 PK와 비교해 비교 연산 비용, 인덱스 크기, 그리고 캐시 효율에서 명확한 차이가 발생한다. 이 부분에 대해서 정리를 조금 하려고 한다.


시작 전 B-tree부터 알고 들어가자

만약에 인덱스가 없다면?

DB는 하단에 보이는것처럼 탐색을 해야함. 이것은 풀스캔 방식. 최악의 경우에 데이터가 100만개가 있으면 100만번 비교를 해야함.

1번 행 → 2번 행 → 3번 행 → ... → N번 행

 

그렇다면 정렬을 하면 해결 되는 문제 아닌가?

정렬이 만약에 안되어 있다면 -> 처음부터 끝까지 다 찾아봐야 함

근데 정렬이 되어 있다면 -> 중간에 펼치고 / 반 갈라서 앞, 뒤 나눠서 비교 가능함

 

B-tree의 핵심은?

  • 항상 정렬되어 있음
  • 한 노드에 여러개의 값이 있음 (2개의 자식을 갖는 이진트리방식와 다름)
  • 트리 높이가 낮음 -> 데이터가 100만개가 되어도 3~4단계 정도만 탐
PRIMARY KEY (id)

프라이머리키(PK)를 걸면 B-tree 인덱스가 자동 생성 됨. 그리고 PK의 값은 B-tree에 정렬된 상태로 저장 됨


BIGINT PK (AUTO_INCREMENT)는 왜 빠를까?

1, 2, 3, 4, 5, 6 ...

B-tree 입장에서 한번 본다면?

  • 항상 맨 뒤에만 추가 됨
  • 기존 구조 안 건드림
  • 페이지 분할 거의 없음
  • 쓰기 성능이 좋음
  • 하지만 분산 서비스 시스템에서 ID 충돌이 일어날수 있음

UUID는 뭐가 다를까?

a3f1...
9b20...
ff12...
1caa...

 

  • 값이 완전히 랜덤
  • 생성 순서 ≠ 정렬 순서

예시 상황

[ 10 | 20 | 30 | 40 ]
     15  ← 중간 삽입
  • 중간 노드에 끼워 넣어야 함
  • 공간 부족하면 페이지 분할(Page Split)
  • 분할되면 트리 구조 재조정
  • 디스크 I/O 증가

정리

"UUID는 문자열이라 느리다" 라기 보다는 B-tree의 정렬을 계속 깨트리고, 페이지 분할이 잦음 그래서 이러한 부분을 해결할수 있는 방법 중 하나가 내부PK는 숫자, 외부 노출은 UUID 로 사용한다.

id (BIGINT PK)
public_id (UUID UNIQUE)

 

참고

https://jangjeonghun.tistory.com/1231

 

bigint VS uuid

Supabase의 UUID 값을 id BigInt @id @default(autoincrement()) 대신 사용하는 것은 일반적으로 안전하며, 많은 경우에 더 나은 선택일 수 있습니다. 각각의 장단점을 고려하여 프로젝트의 요구 사항에 맞게 결

jangjeonghun.tistory.com

https://helloinyong.tistory.com/296

 

데이터베이스 인덱스는 왜 'B-Tree'를 선택하였는가

데이터베이스의 탐색 성능을 좌우하는 인덱스. 인덱스는 데이터 저장, 수정, 삭제에 대한 성능을 희생시켜 탐색에 대한 성능을 대폭 상승하는 방식이라 볼 수 있다. DB의 인덱스는 B-tree 자료구조

helloinyong.tistory.com

 

'PostgreSQL' 카테고리의 다른 글

PostgreSQL 구조 이해하기  (0) 2025.12.17
'PostgreSQL' 카테고리의 다른 글
  • PostgreSQL 구조 이해하기
나는지토
나는지토
  • 나는지토
    안녕은헬로입니다.
    나는지토
  • 전체
    오늘
    어제
    • 분류 전체보기 (27)
      • Backend Design (1)
      • NestJS (19)
        • 개발 (9)
        • 개념과 구조 정리 (10)
      • SpringBoot (0)
      • Java (4)
        • 코테 (0)
      • PostgreSQL (2)
      • Docker (1)
  • 블로그 메뉴

    • 홈
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    역할 검사
    Redis
    nestjs
    nestjs/jwt
    PostgreSQL
    JWT
    db 연결 오류
    토큰 검사
    서비스
    조회 방식
    인증 가드
    컨트롤러
    Collections
    ArrayList
    채팅
    자료구조
    코딩테스트
    커서기반 조회
    BullMQ
    Java
  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
나는지토
UUID PK, 진짜 느릴까? BIGINT와 성능 차이 정리
상단으로

티스토리툴바