JSON은 스키마 없는 유연성을 제공한다. 그러나 유연성은 항상 트레이드 오프를 가져온다. JSON 형식의 데이터도 인덱스를 걸고 빠르게 조회할 수 있을까?

이번 수업에서는 MySQL에서 JSON 데이터의 검색 성능을 최적화하는 가상 컬럼(Virtual Column) 인덱스와 멀티 밸류(Multi-valued)인덱스에 대해 학습해보자.

JSON 검색 성능의 문제점

먼저 인덱스가 없는 상태에서 JSON데이터를 검색할때 어떤 일이 일어나는지 보자.

실행계획을 살펴보자.

-- ## JSON 인덱스와 성능 최적화 1

-- ### JSON 검색 성능의 문제점

-- 실행 계획 확인 (인덱스 없음)
EXPLAIN
SELECT * FROM product_json
WHERE attributes->'$.storage' = 256;

image.png

실행계획의 타입이 ALL이다. 쉽게 말해 풀 테이블 스캔이 일어난다는 것임. 디비엔진이 테이블 첫 행부터 마지막 행까지 모든 행을 하나하나 열어서 값을 확인해야 한다는 점이다.

인덱스가 없으면 이런 풀 테이블 스캔이 일어난다.

그런데 우리가 알고 있는 인덱싱 방식은 컬럼 단위이다. 그런데 JSON은 한 컬럼에 다양한 데이터 형식이 들어있음.

JSON 내부의 특정 키를 인덱스 처럼 사용할 수 있을까?

가상 컬럼을 활용한 인덱스

MySQL 5.7부터 지원하는 가상컬럼을 사용하면 JSON내부의 특정 필드를 마치 별도의 컬럼처럼 추출하고, 여기에 인덱스도 걸 수 있다.

가상 컬럼 생성

ALTER TABLE product_json
ADD COLUMN v_storage INT GENERATED ALWAYS AS (attributes -> '$.storage') VIRTUAL;