※ PostgreSQL: VIEW vs MATERIALIZED VIEW.
안녕하세요. 듀스트림입니다.
오늘은 VIEW와 MATERIALIZED VIEW에 대한 내용입니다.
VIEW는 ANSI SQL 표준입니다.
ANSI SQL에서 VIEW는 가상 테이블로 정의되어 있으며 대부분의 DBMS에서 동일하게 동작합니다.
MATARIALIZED VIEW는 PostgreSQL, Oracle 등에서 지원하는 확장 기능이며 ANSI 표준은 아닙니다.
1. VIEW vs MATERIALIZED VIEW
| 항목 | VIEW | MATERIALIZED VIEW |
| ANSI SQL 표준 지원 | ✅ | ✅ |
| 물리적 데이터 저장 | ❌ | ✅ |
| 쿼리 시 동작 | 원본 테이블 쿼리를 매번 실행 | 저장된 결과 반환 |
| 최신성 | 항상 최신 데이터 반영 | 갱신 전까지는 구버전 데이터 |
| 인덱스 생성 가능 여부 | ❌ | ✅ |
| 수동 갱신 필요 | ❌ | ✅ 필요 (REFRESH) |
2. 성능 및 인덱스 차이
| 항목 | VIEW | MATERIALIZED VIEW |
| 복잡한 집계 성능 | 느림 (실행 시마다 계산) | 빠름 (저장된 결과 사용) |
| 반복 조회 | 매번 다시 계산 | 캐시된 결과 사용 |
| 인덱스 생성 가능 여부 | ❌ | ✅ CREATE INDEX 가능 |
| 병렬 처리 활용 (PostgreSQL) | 쿼리 실행 시 병렬 가능 | 생성/갱신 시 병렬 가능 |
3. 최신화 동작 비교
| 동작 | VIEW | MATERIALIZED VIEW |
| 쿼리 시 최신 데이터 사용 | ✅ | ❌ (REFRESH 필요) |
| 자동 갱신 | ✅ | ❌ |
| 수동 갱신 | 불필요 | REFRESH MATERIALIZED VIEW 필수 |
| REINDEX ... CONCURRENTLY (PostgreSQL) | ❌ (VIEW는 해당 없음) | ✅ (M-VIEW 인덱스) |
4. 예제
▸ 테스트용 테이블, 데이터 생성
CREATE TABLE users (
id SERIAL PRIMARY KEY, -- PostgreSQL은 SERIAL / MySQL은 AUTO_INCREMENT로 변경 가능
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- MySQL에서 SERIAL 사용 시 INT AUTO_INCREMENT로 변경
id INT AUTO_INCREMENT PRIMARY KEY
INSERT INTO users (name, email, is_active, created_at) VALUES
('Alice', 'alice@example.com', TRUE, '2025-07-01 10:00:00'),
('Bob', 'bob@example.com', FALSE, '2025-07-02 11:00:00'),
('Charlie', 'charlie@example.com', TRUE, '2025-07-03 09:30:00'),
('Diana', 'diana@example.com', TRUE, '2025-07-04 14:15:00'),
('Eve', 'eve@example.com', FALSE, '2025-07-05 16:45:00');
4.1 PostgreSQL
▸ VIEW
-- ACTIVE 사용자 뷰 생성
CREATE OR REPLACE VIEW active_users AS
SELECT id, name FROM users WHERE is_active = true;
-- 항상 최신 데이터 조회
SELECT * FROM active_users;
CREATE VIEW
CREATE VIEW CREATE VIEW — define a new view Synopsis CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] …
www.postgresql.org
▸ MATERIALIZED VIEW
-- ACITIVE 사용자 M-VIEW 생성
CREATE MATERIALIZED VIEW mv_active_users AS
SELECT id, name FROM users WHERE is_active = true;
-- M-VIEW는 최신 데이터 반영을 위한 주기적 갱신 필요
REFRESH MATERIALIZED VIEW mv_active_users;
-- M-VIEW에 인덱스 생성
CREATE INDEX idx_mv_active_users_id ON mv_active_users(id);
-- REINDEX
REINDEX INDEX CONCURRENTLY idx_mv_active_users_id;
CREATE MATERIALIZED VIEW
CREATE MATERIALIZED VIEW CREATE MATERIALIZED VIEW — define a new materialized view Synopsis CREATE MATERIALIZED VIEW [ IF NOT EXISTS …
www.postgresql.org
4.2 MySQL
▸ VIEW
CREATE VIEW active_users AS
SELECT id, name FROM users WHERE is_active = true;
SELECT * FROM active_users;
MySQL은 MATERIALIZED VIEW를 지원하지 않습니다.
MySQL :: MySQL 8.4 Reference Manual :: 15.1.23 CREATE VIEW Statement
15.1.23 CREATE VIEW Statement CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}] [DEFINER = user] [SQL SECURITY { DEFINER | INVOKER }] VIEW view_name [(column_list)] AS select_statement [WITH [CASCADED | LOCAL] CHECK OPTION] The CREATE VIEW
dev.mysql.com
5. 팁
- 실시간성과 정확성이 중요한 OLTP 시스템 → VIEW 추천
- 성능 최적화가 중요한 리포트/OLAP → MATERIALIZED VIEW 추천
- M-VIEW 사용 시 반드시 갱신 주기 설계 필요 (cron, pg_cron, job scheduler 등)
- PostgreSQL에서 M-VIEW에 인덱스 추가는 성능 향상 핵심
- MySQL에서는 M-VIEW 대신 별도 테이블 + 트리거 또는 이벤트 스케줄러로 대체 구현
6. 요약 표
| 항목 | VIEW | MATERIALIZED VIEW |
| 저장 방식 | 가상 쿼리 | 물리적 테이블 |
| 최신성 | 항상 최신 | 갱신 시점 기준 |
| 성능 | 느릴 수 있음 | 빠름 (특히 대용량/복잡 쿼리) |
| 인덱스 | 불가능 | 가능 |
| 사용 시점 | OLTP, 실시간 처리 | OLAP, 대시보드, 집계 캐싱 등 |
오늘은 여기까지~
'PostgreSQL' 카테고리의 다른 글
| PostgreSQL: work_mem 최적화 (0) | 2025.08.07 |
|---|---|
| PostgreSQL: pg_upgrade (6) | 2025.08.06 |
| PostgreSQL: Transaction Isolation Level (1) | 2025.07.31 |
| PostgreSQL: Prepared Transaction(2PC) (1) | 2025.07.21 |
| PostgreSQL: pg_waldump (2) | 2025.07.18 |