PostgreSQL은 버전 12부터 테이블 생성 또는 변경 시 정의된 표현식에 따라 값을 자동으로 계산하는 생성 컬럼을 지원했습니다. 기존에는 STORED 방식으로 동작하여 값이 삽입/업데이트 시점에 계산되어 디스크에 물리적으로 저장되었습니다.
VIRTUAL 컬럼의 도입
PostgreSQL 18은 VIRTUAL 한정자를 도입하고 이를 생성 컬럼의 새로운 기본값으로 설정했습니다. VIRTUAL 컬럼은 필요할 때만 쿼리 시점에 값이 계산되므로 디스크 공간을 전혀 사용하지 않습니다.
VIRTUAL과 STORED 컬럼 비교
다음 users 테이블 생성 예시를 통해 두 방식의 차이를 확인할 수 있습니다.
sql
CREATE TABLE users (
id uuid DEFAULT uuidv7() PRIMARY KEY,
email VARCHAR(100) UNIQUE NOT NULL,
first_name VARCHAR(100) NOT NULL,
last_name VARCHAR(100) NOT NULL,
full_name_virtual VARCHAR GENERATED ALWAYS AS (first_name || ' ' || last_name) VIRTUAL,
full_name_stored VARCHAR GENERATED ALWAYS AS (first_name || ' ' || last_name) STORED,
full_name_indexed VARCHAR GENERATED ALWAYS AS (first_name || ' ' || last_name) STORED,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL
);
CREATE INDEX users_full_name_indexed ON users (full_name_indexed);
full_name_virtual은 쿼리 시점에 동적으로 계산되어 디스크에 저장되지 않으며, 인덱스 생성이 불가능합니다. 반면, full_name_stored와 full_name_indexed는 디스크에 저장되며, full_name_indexed와 같이 인덱스를 생성하여 빠른 조회를 지원합니다.
올바른 전략 선택
-
VIRTUAL 사용 시점: 계산이 간단하고 빠르며, 값이 주로 화면 표시에만 필요하고 디스크 사용량을 최소화할 때 적합합니다.
-
STORED 사용 시점: 계산이 복잡하거나 비용이 많이 들고, 생성된 컬럼으로 자주 필터링하거나 정렬해야 하며, 스토리지 공간보다 쿼리 성능이 더 중요할 때 권장됩니다.
EXPLAIN ANALYZE를 통해 쿼리 성능을 분석하여 최적의 컬럼 전략을 결정할 수 있습니다.