PostgreSQL JSONB와 JSON 성능 비교 사례
PostgreSQL에서 JSONB와 JSON의 저장 방식, 인덱싱 영향, 읽기·쓰기 비용을 실사용 관점에서 상세 비교하고 벤치 절차와 쿼리 사례 중심의 검증 결과를 함께 제공
목차
소개
JSON 데이터 타입을 선택할 때는 단순한 문법 차이뿐 아니라 저장 방식과 쿼리 성능 차이를 이해하는 것이 중요하다. 이 글은 PostgreSQL의 json와 jsonb 타입을 비교하면서, 인덱싱과 실제 쿼리 사례를 통해 어느 상황에 어떤 타입이 유리한지 설명한다.
JSON과 JSONB 기본 개념
json 개요
json 타입은 입력된 JSON 텍스트를 그대로 저장한다. 원본의 공백, 키 순서, 중복 키 등 텍스트 형식을 보존한다. 파싱 작업이 필요할 때는 런타임에 해석한다.
jsonb 개요
jsonb는 JSON을 바이너리 형식으로 저장한다. 입력 시 파싱과 정규화(normalization)가 이루어지며, 키 순서가 정렬되고 중복 키는 제거된다. 내부 구조가 인덱싱과 탐색에 유리하게 설계되어 있다.
저장 방식과 성능 차이 원리
쓰기(INSERT/UPDATE) 비용
jsonb는 입력 시 파싱과 재구성 과정이 추가되므로 단건 쓰기 성능에서 json보다 느릴 수 있다. 반면 json은 단순히 문자열로 저장하므로 쓰기 비용이 낮다. 따라서 대량의 단순 로깅처럼 쓰기 중심 워크로드에서는 json이 유리할 수 있다.
읽기(SELECT) 및 쿼리 성능
jsonb는 내부 구조가 탐색에 최적화되어 있어 키 접근, 포함(containment) 쿼리, 인덱스 활용 시 높은 성능을 보인다. 반면 json은 텍스트 파싱이 필요하므로 반복 조회나 복잡한 조건 검색에서 성능 저하가 발생할 가능성이 크다.
인덱싱
가장 큰 차이는 인덱싱 지원이다. jsonb는 GIN, GiST 인덱스를 통해 @> 같은 포함 연산자나 경로 기반 탐색에서 인덱스 스캔을 활용할 수 있다. json 타입은 텍스트이므로 이러한 구조적 인덱싱을 직접 지원하지 않는다.
실무 사례와 검증 절차
간단한 검증 절차는 다음과 같다. 다음 항목을 단계적으로 확인하면 어떤 타입이 적합한지 판단하는 데 도움이 된다.
- 데이터 특성 파악: 읽기 빈도, 쓰기 빈도, 조회 방식
- 인덱싱 필요성 판단: 특정 키에 대한 필터링이 많은지 여부
- 샘플 데이터로 벤치 실행: EXPLAIN ANALYZE와 실제 응답 시간 측정
샘플 테이블과 쿼리 예시
다음 예시는 json과 jsonb 테이블을 만들어 같은 데이터를 넣고 간단한 조회 성능을 비교하는 절차다.
CREATE TABLE t_json (id serial primary key, data json);
CREATE TABLE t_jsonb (id serial primary key, data jsonb);
-- 샘플 데이터 삽입 (예시 단건, 실제는 대량 삽입으로 테스트)
INSERT INTO t_json (data) VALUES ('{"id":1, "name":"alice", "role":"admin", "meta":{"score":42}}');
INSERT INTO t_jsonb (data) VALUES ('{"id":1, "name":"alice", "role":"admin", "meta":{"score":42}}');
-- 인덱스 생성 (jsonb에만 유의미)
CREATE INDEX idx_jsonb_gin ON t_jsonb USING gin (data);
CREATE INDEX idx_jsonb_gin_path ON t_jsonb USING gin (data jsonb_path_ops);
-- 기본 조회 예시
SELECT data->> 'name' FROM t_jsonb WHERE data @> '{"role":"admin"}';
SELECT data->> 'name' FROM t_json WHERE data::jsonb @> '{"role":"admin"}';
위 예시에서 json 타입은 WHERE 절에 바로 @> 연산자를 적용할 수 없으므로 ::jsonb로 캐스팅하면 jsonb와 동일한 연산을 수행할 수 있다. 다만 캐스팅 비용이 쿼리마다 발생한다.
벤치마크 절차 예시
- 동일한 데이터 세트를 두 테이블에 대량 삽입
-
인덱스 유무로 두 환경 비교
-- psql에서 \timing on EXPLAIN ANALYZE SELECT count(*) FROM t_jsonb WHERE data @> '{"role":"admin"}'; EXPLAIN ANALYZE SELECT count(*) FROM t_json WHERE data::jsonb @> '{"role":"admin"}'; - 읽기 지연, CPU 사용량, 디스크 I/O 관찰
실무 권장 사항
다음 가이드라인을 적용하면 결정에 도움이 된다.
- 쿼리와 필터링이 많고 인덱스를 활용할 계획이면 jsonb 선택
- 순수 로그처럼 단순 쓰기만 많고 구조적 검색이 거의 없으면 json 고려
- 중복 키나 키 순서 보존이 필요하면 json 사용을 검토
- 하이브리드 접근으로 일부 컬럼은 정규화하고, 덜 중요한 자유형 필드는 jsonb로 보관
결론
jsonb는 읽기와 구조적 쿼리에서 확실한 장점을 제공하지만, 쓰기 비용과 초기 파싱 오버헤드가 존재한다. 반대로 json은 쓰기 부담이 낮고 원본 텍스트 보존이 필요할 때 유리하다. 최종 선택은 데이터 특성, 조회 패턴, 인덱싱 필요성에 따라 결정되어야 한다. 제안한 벤치 절차를 통해 실제 워크로드 기반 검증을 수행하는 것을 권장한다.