🐘 Released 2025.09.25 · 현행 18.2

PostgreSQL 18
핵심 기능 총정리

비동기 I/O부터 UUIDv7·시간 제약·OAuth까지 — 18 버전이 가져온 30개 신기능을 6개 카테고리로 한눈에.

30 features 6 categories 최대 I/O 성능 Wire Protocol 3.2 (2003년 이후 첫 갱신)
01

⚡ 성능

6 features

비동기 I/O (AIO)

백엔드가 여러 read 요청을 큐에 쌓아 동시 처리. seq scan·bitmap heap scan·vacuum 가속. io_methodworker·io_uring·sync 전환.

최대 3× 처리량

B-tree Skip Scan

멀티컬럼 인덱스에서 선행 컬럼에 = 조건이 없어도 인덱스 활용. prefix 컬럼을 생략한 쿼리의 실행 시간 단축.

멀티컬럼 인덱스 활용↑

OR 조건 인덱스 최적화

WHERE 절의 OR 조건이 인덱스를 활용하도록 개선 — 기존 대비 큰 속도 향상.

Hash / Merge Join 개선

hash join 성능 강화, merge join이 incremental sort를 지원해 정렬 비용 절감.

Parallel GIN 인덱스 빌드

기존 B-tree·BRIN에 더해 GIN 인덱스도 병렬 빌드 지원 — 대용량 trgm/jsonb 인덱스 구축 가속.

ARM NEON / SVE 가속

bit_count()가 쓰는 popcount에 ARM NEON·SVE CPU intrinsic 추가 — ARM 서버에서 비트 연산 가속.

02

🛠️ 개발자 기능

4 features

UUIDv7 네이티브

uuidv7()가 타임스탬프 정렬 UUID 생성 — 인덱스 지역성·캐시 효율↑. uuidv4()gen_random_uuid() 별칭.

신규 PK 권장

Virtual Generated Columns

저장 없이 쿼리 시점에 계산하는 생성 컬럼이 이제 기본값. stored 생성 컬럼은 논리 복제 지원.

기본값 = VIRTUAL

RETURNING OLD / NEW

INSERT·UPDATE·DELETE·MERGERETURNING에서 변경 전(OLD)·후(NEW) 값 동시 참조.

감사·diff 로깅에 유용

Temporal Constraints (WITHOUT OVERLAPS)

시간 범위 제약: PRIMARY KEY·UNIQUEWITHOUT OVERLAPS, FOREIGN KEYPERIOD 절 지원.

03

🔁 복제 (Logical Replication)

4 features

pg_createsubscriber --all

인스턴스 내 모든 DB에 대한 논리 복제본을 단일 명령으로 생성.

Parallel Streaming 기본화

CREATE SUBSCRIPTION이 병렬 스트리밍을 기본 적용 — 트랜잭션 적용 처리량 개선.

Write Conflict 리포팅

복제 쓰기 충돌이 로그에 기록되고 pg_stat_subscription_stats 뷰에서 가시화.

유휴 복제 슬롯 자동 정리

idle_replication_slot_timeout으로 유휴 슬롯 자동 드롭 — WAL 파일 과적재 방지.

04

🔐 보안·인증

5 features

OAuth 2.0 인증

확장을 통한 oauth 인증 메커니즘 — SSO 시스템 연동.

SCRAM Passthrough

postgres_fdw·dblink이 원격 인스턴스에 SCRAM passthrough 인증 지원.

SHA-2 비밀번호 해싱

pgcrypto가 SHA-2 지원. md5 인증은 deprecated(향후 제거 예정).

TLS 1.3 Cipher 설정

ssl_tls13_ciphers 파라미터로 서버 측 TLS 1.3 암호 스위트 지정.

FIPS 모드 검증

암호화 함수의 FIPS 모드 동작 검증 지원 추가.

05

📊 운영·업그레이드·모니터링

7 features

Planner 통계 보존

메이저 업그레이드 시 planner 통계 유지 — 업그레이드 직후 성능 회복 가속(ANALYZE 대기 제거).

업그레이드 다운타임↓

pg_upgrade 강화

--jobs 병렬 체크, 객체 많은 DB 가속, --swap 디렉토리 스왑 플래그.

EXPLAIN 출력 확장

EXPLAIN ANALYZE가 버퍼 접근·인덱스 lookup 횟수 자동 표시, VERBOSE 시 CPU·WAL·read 통계.

모니터링 통계 확장

pg_stat_all_tables에 vacuum 소요 시간, 연결별 I/O·WAL 사용 통계 추가.

페이지 체크섬 기본 활성

initdb로 만든 신규 DB는 page checksum이 기본 on — 데이터 손상 조기 탐지.

선제적 페이지 Freezing

일반 vacuum 중 더 많은 페이지를 선제적으로 freeze — wraparound 위험·집중 vacuum 부담 완화.

Wire Protocol 3.2

2003년(7.4) 이후 첫 새 프로토콜 버전. libpq는 3.0 기본, 신규 클라이언트는 3.2 지원 추가.

06

🔤 텍스트·콜레이션

4 features

PG_UNICODE_FAST 콜레이션

완전한 유니코드 대소문자 변환 + 가속 비교. upper()·lower()·신규 casefold().

비결정적 콜레이션 LIKE

비결정적(nondeterministic) 콜레이션으로 LIKE 패턴 매칭 지원 — 복잡한 다국어 비교.

FTS 콜레이션 Provider

전문 검색이 libc 대신 클러스터 기본 콜레이션 provider 사용(reindex 필요할 수 있음).

CREATE FOREIGN TABLE ... LIKE

로컬 테이블 정의를 그대로 빌려 외부 테이블 스키마 생성 — 보일러플레이트 제거.

🔍

이 프로젝트 쿼리 코드 전수감사

elysia-server · 6개 도메인 병렬 분석

쿼리 보유 약 400개 파일을 6개 도메인으로 나눠 전수분석한 뒤, beta(프로덕션) DB 실제 row 수로 각 이슈를 재판정했다. "코드상 안티패턴"이라도 대상 테이블이 작으면 기각, 클 때만 진짜 이슈로 채택. P0 없음.

0
P0 (치명)
8
P1 (실데이터로 확정)
11
P2 (구조적·중규모)
12
실데이터로 기각

측정된 beta 규모 — lead_contacts 130만 · emails 118만(ws당 53.6만) · leads 114만(ws당 66.5만) · sequence_enrollments 84.3만(시퀀스당 10.8만) · sequence_step_contents 47.6만 · visitor_sessions 5.8만(ws당 5.1만) · activity_logs 5.6만 · email_replies 5,934(ws당 1,810) · notifications 2.5만(user당 100 cap) · linkedin_prospects·utm_visits·iam_audit_logs·nudge_campaigns·buyer_search_analytics = 0

P1 — 우선 수정 (실데이터로 확정된 8건)

심각도위치유형실측 규모 (beta)문제 → 수정
P1sequence-enrollment.service.ts:138·186·323OFFSET시퀀스당 108,147user-facing 목록 3곳. 뒤 페이지일수록 앞부분 재스캔. → (enrolledAt desc, id desc) keyset
P1assessment.service.ts:314·330OFFSETws당 leads 665,389leadScore DESC 평가 화면을 66만 row에 OFFSET. → (leadScore, id) keyset
P1lead-search.service.ts:518OFFSETws당 leads 665,389비-createdAt 정렬 fallback이 66만 row OFFSET. → 정렬키별 복합 keyset
P1visitor.service.ts:692OFFSETws당 51,421OFFSET + 매 호출 full count(*) 2중 비용. → (lastVisitAt, id) keyset
P1personalized-email-data.service.ts:101OFFSET전역 475,573 / lead당 4,299offset 값이 API로 직접 노출 → 깊은 페이지 호출 가능. → (leadId, stepOrder) 복합 keyset
P1lead-search.service.ts:85-146trgm GIN 부재 ILIKEleads 114만website/country/businessType 등 무인덱스 컬럼 leading-wildcard ILIKE → 114만 row seq scan. → trgm GIN 추가 또는 검색 컬럼 축소
P1weekly-digest-data.service.ts:105·249db→analyticsDbemails 118만 ⋈ enroll 84만COUNT(DISTINCT)+대형 LEFT JOIN hashagg를 32MB db로 → 디스크 spill. → analyticsDb(256MB)
P1visitor.service.ts:897·1242db→analyticsDbws당 51,421count(distinct country)+5 FILTER / COUNT(DISTINCT ip)+GROUP BY를 db로 → spill. → analyticsDb

P2 — 구조적 결함 (데이터 규모 무관하게 유효, 11건)

4· 트랜잭션 누락 (원자성)

sequence-auto-enroll 2곳(enrollment↔step_execution 비원자) · bulk-enrollment-scheduling(enrolled인데 execution 없는 영구 미발송 리드 위험) — enrollments 84만 규모라 정합성 깨지면 추적 난해. → db.transaction

4· N+1 쿼리

sales-advisor.queries(행당 5쿼리×50 = ~250 round-trip) · benchmark-comparison · warmup-recovery.worker · sequence bulkUnenroll. → inArray / 단일 GROUP BY 배치화

1· unbounded + 무제한 동시발송

board-email-broadcast: 미구독 전체 유저 limit 없이 로드 후 Promise.allSettled 무제한 동시 발송 → 메모리·SES rate 폭주. → keyset chunk + 동시성 cap

2· db→analyticsDb (중규모)

ui-events 집계 fan-out(activity_logs 5.6만, analyticsDb import 없음) · email-replies-revenue-insights(replies 6k이나 emails 118만 상관 EXISTS). 현재 규모선 spill 경계. → analyticsDb 선제 이전

1· OFFSET (증가 추세)

email-replies.service.ts:158 — 현재 ws당 1,810으로 작지만 단조 증가. 임계 도달 전 keyset 전환 권장. → (createdAt, id) keyset

1· race condition (잠재)

followup-email upsertSessionNudgePending: SELECT→INSERT인데 userId UNIQUE 부재 → 동시 이벤트 중복 발송. 현재 onboarding_session_nudge=0이라 미발현이나 코드 결함. → unique(userId)+ON CONFLICT

~3· trgm GIN 부재 ILIKE (소규모)

hot-lead prefilter · buyer-search(analytics 0 row) — 배치/소규모라 즉각 위험은 낮으나 동일 패턴. → businessType trgm GIN

5· FK 인덱스 누락 (저영향)

sequence_steps.emailSignatureId · enrolledBy/stoppedBy · closedBy · createdBy/registeredBy. SET NULL FK 무인덱스 → 유저/시그니처 삭제 시 seq scan. 삭제 희소라 의도된 트레이드오프.

✕ 실데이터로 기각된 false-positive (12건)

위치코드상 의심실측기각 사유
notification.service.ts:217OFFSET 무한증가 피드user당 100피드에 100건 cap 존재 → OFFSET 깊이 한정, 사실상 무비용
linkedin-sdr-prospect.service.ts:1577·1616OFFSET prospects0 rowlinkedin_prospects 미사용 — 발현 불가
buyer-search analytics/agent-analyticsOFFSET + ILIKE0 / 1.8kbuyer_search_analytics 0 row, lead_discovery_sessions 1.8k 소규모
utm · iam · nudge OFFSETOFFSET 증가 테이블0 rowutm_visits·iam_audit_logs·nudge_campaigns 전부 빈 테이블
admin-ai-sales-team:328 · impersonate:463OFFSET audit/mission576 / 72OFFSET 비용이 의미 없는 소규모
weekly-digest:122 · historyOFFSET history3~6 row극소 — keyset 불필요
billing/* OFFSET 6곳admin 목록 OFFSET소규모admin 전용 + 상품/플랜/구독 수십~수백 row

✓ 클린 (규칙 준수 확인)