View 말고 JSON_TABLE

jinvicky·2025년 4월 23일

SQL

목록 보기
1/8

상황

학생 시험 테이블은 한 컬럼에 직렬화된 JSON 문자열이 통째로 들어가 있다.

학생 a의 시험 응시 정보에 여러 문항 정보가 연결되어 있다. 이 문항 리스트가 1개의 컬럼에 담긴 것이다.

매번 쿼리에서 파싱하거나 자바 코드 작업을 하지 않도록 조치가 필요하다.

1. View

뷰는 테이블처럼 사용할 수 있지만 테이블처럼 데이터를 가지고 있지 않는 가상 테이블이다.

  • 논리적으로만 존재한다. (실제 테이블이 아님)
  • 내가 뷰에 정의한 컬럼만 접근할 수 있다.
  • 인덱스가 적용되지 않는다.
  • 디스크 저장 공간 할당이 이루어지지 않는다.
  • 내용을 바꾸려면 지우고 다시 만들어야 한다. (수정 불가)

json_extract를 사용해서 json을 파싱한 토대로 뷰를 생성하면 자바 코드나 쿼리 단에서 작업 부담이 크게 줄어든다!

근데 앞서 말했듯이 인덱스 적용이 안 된다... 이건 뷰를 못 써먹겠다는 가장 큰 이유다.
데이터 수가 증가하면서 질의 결과가 6초 넘어 나오는 것을 보고 충격받았다.

2. JSON_TABLE

MySQL 8.0 버전부터 지원하는 JSON_TABLE에서 해결책을 찾았다.

  • 테이블처럼 처리하기 때문에 join , group by 가 가능하다.
  • 전체 데이터를 다 json_table로 만드는 것이 아니라 조인한 데이터에 한해서 일부만 테이블로 만들기 때문에 성능에서 유리하다.
-- JSON 데이터
SET @json_data = '
[
  { "name": "Alice", "age": 30 },
  { "name": "Bob", "age": 25 },
  { "name": "Charlie", "age": 35 }
]';

-- JSON_TABLE 사용 예제
SELECT *
FROM JSON_TABLE(
  @json_data,
  '$[*]' -- 배열의 모든 요소
  COLUMNS (
    name VARCHAR(100) PATH '$.name',
    age INT PATH '$.age'
  )
) AS jt;

성능

  • 뷰에서 jsonTable로 바꾸고 성능을 6초에서 1초대로 단축했다.

Outro

뷰를 중복 테이블을 제거하기 위해 사용하기도 하고 민감 정보를 숨기고 일부만 보여주기 위해 사용하는 경우도 있다.

이번 글에서의 핵심은 뷰는 편리하지만 큰 데이터를 다루기에 성능 측면에서 부적합하다는 점이다.

뷰는 원본 테이블을 기반으로 매번 다시 계산하고, 뷰 자체에 인덱스 추가와 같은 성능 개선을 시도할 수 없다. (원본 테이블을 수정해야 한다)

profile
개발, 그림, 기록

0개의 댓글