멀티테넌시 격리, 스키마와 RLS 중 무엇을 먼저 봐야 하나?

결론부터 말하면 정답은 테넌트 수와 쿼리 패턴에 달려 있다. 인덱스가 제대로 잡힌 RLS는 쓰기·읽기 모두 스키마 격리와 비등하거나 앞서지만, 인덱스가 빠지면 전체 스캔으로 무너진다. 스키마 격리는 테넌트가 많아질수록 카탈로그와 마이그레이션 관리 비용이 누적된다.

  • RLS는 단일 테이블·단일 인덱스 구조라 쓰기 처리량에서 근소하게 유리하다.
  • 스키마 격리는 테넌트별 인덱스가 개별 관리되어 읽기 격리는 명확하지만 운영 오버헤드가 커진다.
  • RLS의 진짜 위험은 정책 누락이 아니라 tenant_id 인덱스 부재다.
  • 스키마 격리의 진짜 위험은 성능이 아니라 카탈로그 폭증이다.
  • 두 방식 모두 "격리 강도"와 "운영 비용"이 반비례한다.

두 방식을 나란히 놓으면 이렇다. 스키마 격리(schema-per-tenant)는 테넌트마다 독립된 스키마를 만들어 물리적으로 데이터를 분리한다. RLS는 단일 테이블에 tenant_id 컬럼을 두고 정책(policy)으로 행 단위 접근을 제어한다. 전자는 격리가 구조적으로 보장되고, 후자는 격리가 쿼리 플래너와 정책 평가에 위임된다.

쓰기 성능은 어느 쪽이 앞서나?

RLS가 근소하게 앞선다. PostgreSQL 16 + AWS RDS db.m6g.xlarge(4 vCPU, 16GB) 환경, 1,000 테넌트·1,000만 행 조건에서 RLS는 18,500 inserts/sec(평균 3.2ms, p95 8.1ms, CPU 42%)를, 스키마 격리는 16,200 inserts/sec(평균 3.8ms, p95 12.3ms, CPU 38%)를 기록했다는 벤치마크가 있다 propelius.ai. 단일 B-tree 인덱스로 쓰기 경로가 단순한 것이 RLS 쪽에 유리하게 작용한 것으로 보인다.

읽기 성능은 인덱스 유무에 따라 어떻게 갈리나?

인덱스가 없으면 RLS가 전체 스캔으로 무너진다. 같은 벤치마크에서 tenant_id 인덱스가 없는 상태의 풀 스캔 읽기는 RLS 280ms(1,000만 행 스캔, seq scan)인 반면 스키마 격리는 3ms(1만 행 스캔, index scan)였다. 그런데 tenant_id 인덱스를 추가하자 RLS 4.1ms, 스키마 격리 3.2ms로 격차가 거의 사라졌다 propelius.ai. 즉 RLS 자체의 한계가 아니라 인덱싱 설계 누락이 성능 함정의 실체다.

운영·카탈로그 복잡도는 테넌트 수가 늘어나면 어떻게 변하나?

스키마 격리는 테넌트 수가 늘수록 카탈로그가 병목이 된다. 커뮤니티 벤치마크 기준으로 스키마-퍼-테넌트는 약 500 테넌트까지는 예측 가능하지만, 그 이상에서는 카탈로그 조회와 스키마별 인덱스 관리(1,000 테넌트면 인덱스 1,000개)가 부담으로 작용한다는 보고가 있다 toolchew.com. 반대로 RLS는 정책 작성이 잘못되면 busy table에서 성능이 급락할 수 있다는 지적도 같은 자료에서 나온다. 다만 이 수치들은 통제된 벤치마크가 아니라 서술형 경고에 가깝다는 점은 짚어둘 필요가 있다.

실측 수치로 보면 격차는 얼마나 벌어지나?

항목 RLS (단일 테이블) 스키마-퍼-테넌트
Insert 처리량 18,500/sec 16,200/sec
평균 지연 3.2ms 3.8ms
p95 지연 8.1ms 12.3ms
풀스캔 읽기(인덱스 無) 280ms, 1,000만 행 3ms, 1만 행
인덱스 적용 읽기 4.1ms 3.2ms
CPU 사용률 42% 38%

수치 출처는 동일 벤치마크다 propelius.ai. 표에서 드러나듯 격차는 절대적이지 않고, 인덱스 설계 여부에 따라 뒤집힌다.

스키마에서 RLS로, 혹은 그 반대로 옮기면 무엇이 드나?

전환 비용은 데이터 이동보다 애플리케이션 계층의 쿼리 재작성에 집중된다. 스키마 격리에서 RLS로 옮길 때는 모든 테이블에 tenant_id 컬럼을 추가하고, 기존 스키마별 데이터를 단일 테이블로 병합한 뒤 정책을 새로 작성해야 한다. 여기에 tenant_id 인덱스를 처음부터 정확히 설계하지 않으면 앞서 본 280ms 풀스캔 함정을 그대로 재현하게 된다. 반대로 RLS에서 스키마 격리로 옮길 때는 테넌트 수만큼 스키마와 인덱스를 새로 생성하고, 마이그레이션 도구(예: 스키마별 DDL 배포)를 테넌트 수에 맞춰 병렬화해야 한다. 두 방향 모두 다운타임 없이 전환하려면 이중 쓰기(dual write) 기간을 거치는 것이 일반적이다.

그래서 어떤 조건에서 어느 쪽을 써야 하나?

정답은 테넌트 수, 쿼리 패턴, 컴플라이언스 요구 세 축으로 갈린다. 테넌트 수가 수백 단위이고 테넌트별 완전한 물리적 분리가 요구되면(예: 규제상 데이터 분리 증빙) 스키마 격리가 관리하기 쉽다. 테넌트 수가 수천 이상이고 tenant_id 인덱스를 처음부터 정확히 설계할 수 있다면 RLS가 인프라 비용과 관리 부담 모두에서 유리하다. CPU 집약적 워크로드에서는 컨테이너·DB 분리가, 메모리 집약적 워크로드에서는 오히려 분리가 비효율적이라는 보고도 있어 openproceedings.org, 워크로드 성격을 먼저 진단하는 편이 격리 방식을 먼저 정하는 것보다 안전하다. 2026년 기준으로도 이 판단 순서는 바뀌지 않았다.

핵심 정리

  • RLS와 스키마 격리의 성능 격차는 인덱스 설계 여부로 대부분 설명된다.
  • RLS는 tenant_id 인덱스가 없으면 풀스캔으로 급락하고, 스키마 격리는 테넌트 수가 늘수록 카탈로그·인덱스 관리 부담이 커진다.
  • 실측 벤치마크(1,000 테넌트, 1,000만 행)에서는 쓰기·읽기 모두 두 방식의 차이가 크지 않았다 propelius.ai.
  • 전환 비용은 데이터 이동이 아니라 쿼리·정책·인덱스 재설계에 집중된다.
  • 선택 기준은 성능 우열이 아니라 테넌트 수, 쿼리 패턴, 컴플라이언스 요구다.

참고 자료

더 알아보기

데이터베이스 선택의 실체: 워크로드로 읽는 판단 기준 — 이 주제의 종합 가이드