[프롬프트] SQL 쿼리 최적화 프롬프트 - 최적 프롬프트 레시피

SQL 쿼리 최적화 및 실행 계획 분석

[프롬프트] SQL 쿼리 최적화 프롬프트 - 최적 프롬프트 레시피

💡 한 줄 요약: "이 SQL 쿼리 빠르게 튜닝해줘"라는 단순 질의 시 터져 나오는 '인덱스 맹목적 추가'와 '불필요한 서브쿼리 제거' 식의 겉핥기 조언을 완전히 타파하고, Principal DBA 관점의 실행 계획(EXPLAIN ANALYZE) 해체, 카디널리티 기반 조인 재설계, 커버링 인덱스, Keyset No-Offset 페이지네이션까지 완벽히 도출하는 실무 종결 프롬프트 레시피입니다.

1. 페인포인트 & 작업 목표

  • 실무 상황: 서비스 사용자가 급증하면서 일일 수천만 건 테이블의 집계 쿼리가 수 초 이상 지연되거나, 백오피스/모바일 피드의 깊은 페이지네이션(Deep OFFSET)으로 인해 DB CPU 사용률이 100%에 달해 커넥션 풀이 고갈되는 위기 상황.
  • 단순 프롬프트 요청 시 발생하는 4대 전형적 문제:
    • 실행 계획 부재로 인한 맹목적 인덱스 남발(Blind Index Creation): 테이블 데이터 분포(Cardinality)나 블록 I/O 통계를 모른 채 WHERE 절 컬럼마다 단일 인덱스를 걸라고 조언하여, 쓰기(CUD) 성능을 파괴하고 인덱스 스캔 효율을 망가뜨림.
    • RDBMS 엔진 특성 무시(Engine Agnostic Fallacy): PostgreSQL 16의 병렬 해시 조인(Parallel Hash Join)이나 JIT 컴파일 특성, MySQL 8.0의 인덱스 컨디션 푸시다운(ICP) 및 버퍼 풀 메커니즘을 고려하지 않고 범용 ANSI-SQL 문법 수정만 제시함.
    • Deep OFFSET 페이징 병목 방치: 수십만 번째 페이지를 조회할 때 앞선 수십만 행을 전부 읽고 버리는 OFFSET의 디스크 I/O 낭비를 인식하지 못하고, 단순히 LIMIT 수치만 줄이라는 무의미한 답을 제시함.
    • 메모리 버퍼 캐시 및 임시 테이블 누수 간과: 정렬(ORDER BY)이나 임시 테이블 생성이 디스크(On-Disk Temp Table, WorkMem Spill)로 쏟아지는 현상을 진단하지 못함.
  • 해결 목표:
    • Principal DBA & Query Tuning Architect 페르소나 주입: 실행 계획의 Cost 트리, 행 추정치(Est. Rows) vs 실제 행(Actual Rows) 오차, 버퍼 히트율(Shared Hit)을 정밀 분석.
    • 3단계 쿼리 튜닝 아키텍처 강제: [실행 계획 병목 원인 규명 → 인덱스 및 스키마 물리적 최적화 → SQL 문장 및 커서 재작성].
    • 유형별 전용 레시피 분리: 대용량 다중 조인/집계 병목을 위한 종합 튜닝(레시피 B)과 5,000만 건 대규모 페이징/슬로우 쿼리 10초 킬러(레시피 C)의 이원화.

2. 프롬프트 레시피 비교

❌ 레시피 A: 기본형 (단순 질의 초안)

스키마 정의나 실행 계획 없이 SQL 문장만 던지고 튜닝을 요구하는 초안입니다:

영문 프롬프트 (복사용)
Optimize this SQL query to make it faster:
[PASTE_SQL_QUERY_HERE]
한글 프롬프트 (1:1 매칭 복사용)
이 SQL 쿼리를 더 빠르게 최적화해 주세요:
[여기에_SQL_쿼리_붙여넣기]
💡 프롬프트 구조 및 핵심 파라미터 해설란
  • 구조적 결함: DB 엔진 종류(PostgreSQL, MySQL, Oracle), 테이블 행 수(Volume), 기존 인덱스 명세, EXPLAIN 결과가 완전히 누락되었습니다.
  • 부작용: AI는 SELECT *를 컬럼 나열로 바꾸거나, WHERE 절 컬럼에 인덱스를 무조건 추가하라는 교과서적이고 실효성 없는 답변만 반복합니다.
⚡ 레시피 B: 실무 종결형 Principal DBA 쿼리 튜닝 프롬프트

RDBMS 버전, 테이블 볼륨, 기존 DDL 인덱스, EXPLAIN ANALYZE 버퍼 통계를 함께 주입하여 디스크 I/O와 CPU 연산을 최소화하는 종합 진단 레시피입니다:

영문 프롬프트 (복사용)
You are a Principal Database Administrator (DBA) and High-Throughput Query Performance Architect specializing in storage engines, query planners, and cost-based optimizers.
Analyze the provided SQL query, execution plan, schema DDL, and table cardinality to construct an optimized query and indexing strategy.

### Target Environment & Telemetry:
- Database Engine & Version: [e.g., PostgreSQL 16.2 / MySQL 8.0.36 InnoDB]
- Table Schemas & Row Volume:
[PASTE_CREATE_TABLE_DDL_AND_APPROX_ROW_COUNTS_HERE]
- Existing Indexes:
[PASTE_EXISTING_INDEXES_AND_CONSTRAINTS_HERE]
- Slow SQL Query:
[PASTE_SLOW_SQL_QUERY_HERE]
- Execution Plan (EXPLAIN (ANALYZE, BUFFERS) / EXPLAIN ANALYZE):
[PASTE_EXPLAIN_OUTPUT_HERE]

### Performance Deliverable Requirements:
1. EXECUTION PLAN BOTTLENECK AUDIT:
   - Identify node-by-node bottlenecks (e.g., Seq Scan vs Index Scan, nested loop spill, HashAggregate memory overflow).
   - Flag discrepancies between Estimated Rows and Actual Rows (stale table statistics/planner miscalculation).
2. HARDWARE & BUFFER CACHE IMPACT:
   - Measure shared buffer cache hits vs disk reads (Shared Hit vs Read Blocks) and temp file usage.
3. PHYSICAL SCHEMA & COMPOSITE INDEX DESIGN:
   - Suggest minimal, high-efficiency composite indexes using (Equality, Range, Sort) order and covering columns (INCLUDE).
4. REWRITTEN HIGH-PERFORMANCE SQL:
   - Provide the refactored SQL utilizing derived tables, CTE materialized controls, or Sargable predicates.
5. PRE/POST LATENCY & COST PROJECTION:
   - Estimate expected query execution time and disk I/O reduction ratio.
한글 프롬프트 (1:1 매칭 복사용)
당신은 스토리지 엔진, 쿼리 플래너, 비용 기반 최적화기(CBO)를 전문으로 하는 수석 데이터베이스 관리자(Principal DBA)이자 대용량 쿼리 성능 아키텍트입니다.
제공된 SQL 쿼리, 실행 계획, 스키마 DDL, 테이블 카디널리티를 분석하여 최적화된 쿼리 및 인덱싱 전략을 도출하십시오.

### 대상 환경 및 텔레메트리:
- 데이터베이스 엔진 및 버전: [예: PostgreSQL 16.2 / MySQL 8.0.36 InnoDB]
- 테이블 스키마 및 행 볼륨:
[여기에_CREATE_TABLE_DDL_및_대략적_행_수_붙여넣기]
- 기존 인덱스 내역:
[여기에_기존_인덱스_및_제약조건_붙여넣기]
- 슬로우 SQL 쿼리:
[여기에_슬로우_SQL_쿼리_붙여넣기]
- 실행 계획 (EXPLAIN (ANALYZE, BUFFERS) / EXPLAIN ANALYZE):
[여기에_실행_계획_출력_붙여넣기]

### 성능 최적화 산출물 요구사항:
1. 실행 계획 병목 노드 정밀 진단:
   - 노드별 병목을 식별하십시오 (예: Seq Scan vs Index Scan, 중첩 루프 유출, HashAggregate 메모리 초과).
   - 추정 행 수(Estimated Rows)와 실제 행 수(Actual Rows) 간의 괴리를 지적하십시오 (통계 미갱신 및 플래너 오판 분석).
2. 하드웨어 및 버퍼 캐시 영향 분석:
   - 공유 버퍼 캐시 히트율 대비 디스크 I/O(Shared Hit vs Read Blocks)와 임시 디스크 파일 사용량을 측정하십시오.
3. 물리 스키마 및 결합 인덱스 설계:
   - (등치 조건, 범위 조건, 정렬 순서) 규칙과 커버링 인덱스(INCLUDE 컬럼)를 적용한 최소한의 고효율 복합 인덱스를 제안하십시오.
4. 재작성된 고성능 SQL:
   - 유도 테이블(Derived Table), CTE 구체화 제어, 또는 Sargable 조건식을 적용하여 재작성된 SQL을 제공하십시오.
5. 튜닝 전/후 지연시간 및 I/O 비용 비교:
   - 예상 쿼리 실행 시간 단축치 및 디스크 I/O 감소 비율을 명시하십시오.
💡 프롬프트 구조 및 핵심 파라미터 해설란
  • CBO 및 실행 계획 분석 강제: 쿼리 텍스트만 보고 어림짐작하는 대신 Seq Scan, Disk WorkMem Spill 등 실제 엔진이 수행한 물리적 오버헤드를 타겟팅합니다.
  • 인덱스 설계 3원칙(Equality → Range → Sort): WHERE 절과 ORDER BY 절의 복합 인덱스 컬럼 배치 순서를 엄격히 통제하여 불필요한 Filesort를 완전히 제거합니다.
  • 커버링 인덱스(INCLUDE): 인덱스 리프 노드에 조회 컬럼을 포함시켜 메인 테이블 데이터 블록(Heap/Clustered) Random Access를 원천 차단합니다.
🚀 레시피 C: 대규모 페이징 & 슬로우 쿼리 10초 튜닝 (Keyset Pagination & Subquery Killer)

5,000만 건 이상의 대형 테이블에서 OFFSET 100000 이상 조회 시 수 초간 멈추는 병목이나 N+1 상관 서브쿼리를 즉각 제거하는 전용 레시피입니다:

영문 프롬프트 (복사용)
You are an Extreme Low-Latency SQL Performance Engineer specializing in Keyset (No-Offset) Pagination and Anti-Pattern Subquery Elimination.
Refactor the provided slow query to achieve sub-10ms response time on 50M+ row tables without table locking.

### Slow Query Bottleneck Specs:
- RDBMS Engine: [e.g., MySQL 8.0 InnoDB / PostgreSQL 16]
- Query Pattern: [e.g., OFFSET 500000 Pagination / Correlated Scalar Subquery in SELECT / NOT IN Nullable Anti-Join]
- Query Text:
[PASTE_OFFENDING_QUERY_HERE]
- Table Primary Key & Clustered Key: [e.g., BIGINT AUTO_INCREMENT `id`, `created_at` DESC]

### Immediate 3-Step Refactoring Plan:
1. NO-OFFSET KEYSET CURSOR CONVERSION:
   - Replace linear-scan `OFFSET/LIMIT` with deterministic seek predicate (`WHERE (created_at, id) < (:last_created_at, :last_id) LIMIT :size`).
2. ANTI-JOIN & SUBQUERY DE-CORRELATION:
   - Transform correlated scalar subqueries or `NOT IN` clauses into hash-efficient `LEFT JOIN ... WHERE right.key IS NULL` or CTE Window partitions.
3. CONCURRENT ZERO-DOWNTIME DDL:
   - Provide exact non-blocking index creation DDL (e.g., `ALGORITHM=INPLACE, LOCK=NONE` for MySQL or `CREATE INDEX CONCURRENTLY` for PostgreSQL).
한글 프롬프트 (1:1 매칭 복사용)
당신은 Keyset(No-Offset) 페이지네이션 및 안티패턴 서브쿼리 제거를 전문으로 하는 초저지연 SQL 성능 엔지니어입니다.
제공된 슬로우 쿼리를 리팩토링하여 5,000만 건 이상의 테이블에서도 락 없이 10ms 이내 응답을 달성하도록 변환하십시오.

### 슬로우 쿼리 병목 스펙:
- RDBMS 엔진: [예: MySQL 8.0 InnoDB / PostgreSQL 16]
- 쿼리 패턴: [예: OFFSET 500000 페이지네이션 / SELECT 절 상관 스칼라 서브쿼리 / NOT IN Nullable 안티 조인]
- 쿼리 본문:
[여기에_병목_쿼리_붙여넣기]
- 테이블 기본키 및 클러스터 키: [예: BIGINT AUTO_INCREMENT `id`, `created_at` DESC]

### 즉시 실행 3단계 리팩토링 계획:
1. No-Offset Keyset 커서 변환:
   - 선형 스캔 방식의 `OFFSET/LIMIT`를 결정론적 탐색 조건문(`WHERE (created_at, id) < (:last_created_at, :last_id) LIMIT :size`)으로 교체하십시오.
2. 안티 조인 및 서브쿼리 비상관화:
   - SELECT 절 상관 스칼라 서브쿼리나 `NOT IN` 구문을 해시 조인에 유리한 `LEFT JOIN ... WHERE right.key IS NULL` 또는 윈도우 파티션으로 재작성하십시오.
3. 무중단 인덱스 생성 DDL:
   - 서비스 중단 없이 적용 가능한 안전한 DDL을 제공하십시오 (예: MySQL `ALGORITHM=INPLACE, LOCK=NONE`, PostgreSQL `CREATE INDEX CONCURRENTLY`).
💡 프롬프트 구조 및 핵심 파라미터 해설란
  • Keyset Seek 연산 강제: OFFSET N은 N개의 레코드를 전부 읽은 후 버리는 $O(N)$ 연산이지만, 마지막 커서 키를 활용한 Keyset 탐색은 B-Tree 인덱스를 타고 즉시 진입하는 $O(\log N)$ 연산으로 고정됩니다.
  • 무중단 DDL(Non-blocking DDL): 프로덕션 5,000만 건 테이블에 단순 CREATE INDEX를 날리면 전체 테이블 락(Exclusive Lock)이 걸려 대형 장애가 발생하므로 무중단 옵션을 필수 조건으로 강제합니다.

3. 실행 결과 비교: 레시피 A vs B vs C 실전 대조

❌ 레시피 A 실행 결과: [단순 질의의 한계] 실행 계획 없는 맹목적 인덱스 추가 조언

레시피 A에 1,000만 건 주문-결제 조인 슬로우 쿼리를 입력했을 때의 결과입니다:

-- ❌ AI의 단순 답변: WHERE 조건 컬럼들에 개별 인덱스를 마구 추가하라는 조언
CREATE INDEX idx_orders_status ON orders(status);
CREATE INDEX idx_orders_created_at ON orders(created_at);
CREATE INDEX idx_payments_method ON payments(method);

SELECT o.id, o.user_id, o.total_amount, p.status
FROM orders o
JOIN payments p ON o.id = p.order_id
WHERE o.status = 'COMPLETED'
  AND o.created_at >= '2026-01-01'
  AND p.method = 'CREDIT_CARD';
👉 비판:
• orders.status의 카디널리티가 낮아(COMPLETED가 전체의 85% 차지) 인덱스를 생성해도 PostgreSQL 옵티마이저는 인덱스를 무시하고 풀 테이블 스캔(Seq Scan)을 선택합니다.
• 개별 단일 인덱스는 인덱스 머지(Bitmap Index Scan) 비용만 가중시키며, 테이블 랜덤 I/O를 전혀 줄여주지 못해 응답 속도가 4.8초에서 거의 개선되지 않습니다.

⚡ 레시피 B 실행 결과: [실전 사례 1] 1,000만 건 주문·결제 다중 조인 및 집계 슬로우 쿼리 튜닝

PostgreSQL 16 환경에서 18만 개 디스크 블록을 읽던 Full Seq Scan을 부분 복합 커버링 인덱스와 인덱스 온리 스캔으로 전환하여 4.8초에서 12ms로 400배 단축시킨 사례입니다.

1) 1차 입력 텔레메트리 주입

  • 환경: PostgreSQL 16.2, SSD NVMe, shared_buffers = 8GB
  • 볼륨: orders 1,000만 행 (COMPLETED 85%, PENDING 15%), payments 1,000만 행
  • 실행 계획: Gather (cost=214500.00..385400.00 rows=350000 width=32) (actual time=120.4..4810.2ms) → Seq Scan on orders (Buffers: shared read=184,200)

2) AI 생성 출력 결과 (핵심 발췌)

1. 실행 계획 병목 정밀 진단
  • 병목 지점: orders 테이블에서 184,200개 디스크 블록을 읽는 Full Sequential Scan 발생 (4,810ms 중 4,100ms 소모).
  • 플래너 원인: status='COMPLETED'의 낮은 선택도(Selectivity 85%)로 인해 단일 컬럼 인덱스를 포기하고 디스크 순차 스캔으로 폴백됨.
  • 버퍼 상태: Buffer Shared Hit 12%에 불과하여 매번 디스크 NVMe I/O를 직접 유발함.
2. 고효율 부분 복합 인덱스 & 커버링 설계 (PostgreSQL 16)

전체 테이블이 아닌 상태값과 기간을 커버하는 부분 복합 인덱스(Partial Composite Covering Index) 생성:

-- 1. 무중단 부분 커버링 인덱스 생성
CREATE INDEX CONCURRENTLY idx_orders_completed_date_covering
ON orders (created_at DESC)
INCLUDE (id, user_id, total_amount)
WHERE status = 'COMPLETED';

-- 2. 조인 외래키 인덱스
CREATE INDEX CONCURRENTLY idx_payments_order_id_method
ON payments (order_id)
INCLUDE (status)
WHERE method = 'CREDIT_CARD';
3. 리팩토링된 SQL 쿼리 (인덱스 온리 스캔 유도)

인덱스 온리 스캔(Index Only Scan)을 유도하고 조인 대상 튜플을 선행 필터링:

SELECT /*+ IndexOnlyScan(o) */
    o.id,
    o.user_id,
    o.total_amount,
    p.status AS payment_status
FROM orders o
INNER JOIN payments p ON p.order_id = o.id AND p.method = 'CREDIT_CARD'
WHERE o.status = 'COMPLETED'
  AND o.created_at >= '2026-01-01 00:00:00'
ORDER BY o.created_at DESC
LIMIT 50;
4. 튜닝 결과 검증
  • 수행 방식: Seq Scan (4,810ms) → Index Only Scan using idx_orders_completed_date_covering (11.8ms)
  • 블록 I/O: shared read=184,200 → shared hit=42, read=0 (메모리 버퍼 100% 히트)
  • 지연시간 개선: 4.8초에서 12ms로 400배 성능 향상 달성

3) 후속 프롬프트 체이닝 (2종)

① 파티셔닝(Partitioning) 확장 체이닝:
👉 "이 테이블이 연간 5,000만 건 이상으로 증가할 경우를 대비하여 created_at 기준 분기별 PostgreSQL Range Partitioning 및 파티션 프루닝(Partition Pruning) 적용 DDL 스크립트를 작성해줘."

② TypeORM / Prisma ORM 최적화 체이닝:
👉 "위 인덱스 온리 스캔 힌트와 조인 방식을 유지한 채 NestJS Prisma ORM의 $queryRaw 타입 안전 쿼리로 변환해줘."

4) 4단계 적용 워크플로우

  1. EXPLAIN (ANALYZE, BUFFERS) 캡처: 디스크 읽기 블록 수와 선택도 오차 식별.
  2. 레시피 B 프롬프트 진단: 부분 인덱스 조건(WHERE status='COMPLETED') 및 INCLUDE 컬럼 산출.
  3. 무중단 CONCURRENT DDL 배포: 프로덕션 락 없이 백그라운드 인덱스 빌드.
  4. 인덱스 온리 스캔 검증: Actual Rows가 50행에서 즉각 멈추는지(Early Stop) 확인.

🚀 레시피 C 실행 결과: [실전 사례 2] 5,000만 건 게시글 Deep Pagination (OFFSET 500000) 병목 해결

MySQL 8.0 환경에서 50만 건 행을 디스크에서 순차 스캔하느라 3.2초가 걸리던 Deep OFFSET을 Keyset 커서 비교로 전환하여 2.1ms로 1,500배 향상시킨 사례입니다.

1) 1차 입력 텔레메트리 주입

  • 환경: MySQL 8.0.36 InnoDB
  • 슬로우 쿼리: SELECT id, title, author_id, view_count, created_at FROM articles WHERE category_id = 4 ORDER BY created_at DESC, id DESC LIMIT 20 OFFSET 500000;
  • 현상: 50만 번째 행을 건너뛰기 위해 앞선 50만 건의 B-Tree 클러스터드 인덱스를 순회하느라 쿼리 1건당 3.2초 소모 및 CPU 급증

2) AI 생성 출력 결과 (핵심 발췌)

1. Keyset No-Offset 커서 변환 SQL

OFFSET 500000을 물리적으로 제거하고 직전 페이지 마지막 튜플의 (created_at, id) 튜플 비교 탐색으로 전환:

-- 프론트엔드에서 직전 페이지의 마지막 항목 (:last_created_at, :last_id) 전달받음
SELECT 
    id, 
    title, 
    author_id, 
    view_count, 
    created_at
FROM articles
WHERE category_id = :category_id
  AND (created_at < :last_created_at 
       OR (created_at = :last_created_at AND id < :last_id))
ORDER BY created_at DESC, id DESC
LIMIT 20;
2. 무중단 복합 인덱스 DDL (MySQL 8.0 In-Place)

Keyset 튜플 정렬과 필터링을 한 번의 인덱스 탐색(Index Seek)으로 끝내기 위한 복합 인덱스 생성:

ALTER TABLE articles 
ADD INDEX idx_category_created_id (category_id, created_at DESC, id DESC),
ALGORITHM=INPLACE, 
LOCK=NONE;
3. 성능 개선 지표
  • Rows Examined: 500,020행 탐색 → 정확히 20행 탐색 (99.99% 축소)
  • 실행 시간: 3,240ms → 2.1ms (약 1,500배 속도 향상)
  • 정렬 비용: Filesort 발생 없음 (B-Tree 인덱스 순서 그대로 반환)

3) 후속 체이닝: 커버링 인덱스 결합 지연 조인(Deferred Join) 체이닝

사용자 추가 프롬프트:
👉 "만약 모바일 앱 클라이언트가 특정 페이지 번호로 다이렉트 점프(Direct Page Jump)를 반드시 요구한다면, OFFSET을 쓰더라도 지연 조인(Deferred Join)을 적용해 데이터 블록 Random Access를 최소화하는 서브쿼리 최적화 SQL을 작성해줘."

💡 결과: AI가 SELECT ... FROM articles a JOIN (SELECT id FROM articles WHERE ... LIMIT 20 OFFSET 500000) AS sub ON a.id = sub.id 구조를 도출하여, 50만 건에 대해 기본키 인덱스만 스캔하게 만들어 실행 시간을 3.2초에서 180ms로 18배 단축시키는 절충안을 제시함.

4) 3단계 긴급 최적화 워크플로우

  1. OFFSET 패턴 감지: API 로그에서 10,000페이지 이상의 비정상 딥 페이지네이션 확인.
  2. Keyset SQL 및 복합 인덱스 도출: 레시피 C로 No-Offset 조건식 및 In-Place DDL 확보.
  3. 무중단 적용 및 벤치마크: LOCK=NONE 인덱스 생성 후 응답 시간 2ms 확정.

4. 옵티마이저 튜닝 메커니즘 심층 분석

  • 1. Sargable(Search Argument Able) 조건식의 절대성:
    • WHERE YEAR(created_at) = 2026 또는 WHERE status || '' = 'ACTIVE'와 같이 컬럼을 가공하는 식은 인덱스 컬럼의 정렬 순서를 무력화하여 무조건 Full Table Scan을 발생시킵니다.
    • 프롬프트는 이를 WHERE created_at >= '2026-01-01' AND created_at < '2027-01-01' 형태의 범위 비교로 강제 전환하여 B-Tree Index Range Scan을 복원합니다.
  • 2. 인덱스 스킵 스캔(Index Skip Scan)과 선두 컬럼 규칙:
    • 복합 인덱스 (A, B, C)에서 선두 컬럼 A 없이 WHERE B = 1로만 조회할 경우, 최신 MySQL 8.0 이상에서 Index Skip Scan이 작동할 수 있으나 유니크 카디널리티가 높으면 효율이 급감합니다.
    • 프롬프트는 쿼리 패턴의 실제 필터링 빈도를 기반으로 복합 인덱스 컬럼의 최적 선행 배치 순서를 자동으로 재조정합니다.
  • 3. Driving Table(선행 테이블) 선정 메커니즘:
    • Nested Loop Join 시 가장 작은 결과 집합을 가진 테이블이 Outer Driving Table이 되어야 Inner 테이블의 인덱스를 타고 $O(\log N)$으로 탐색할 수 있습니다.
    • AI는 카디널리티 통계를 바탕으로 STRAIGHT_JOIN이나 pg_hint_plan의 선행 힌트를 제시하여 플래너의 잘못된 조인 순서를 교정합니다.

5. 실전 투입용 플레이스홀더 템플릿

실무에서 슬로우 쿼리가 발생했을 때 즉각 복사하여 값만 채워 넣을 수 있는 최종 템플릿입니다:

[역할]
당신은 대규모 RDBMS 성능 튜닝을 전담하는 Principal DBA입니다.

[시스템 환경]
- RDBMS: [MySQL 8.0 / PostgreSQL 16 / Oracle 19c]
- 버퍼 풀 / WorkMem 크기: [예: innodb_buffer_pool_size=16GB / work_mem=64MB]

[테이블 명세 & 데이터 규모]
- 메인 테이블: [테이블명] (약 [건수] 행)
- 조인 대상 테이블: [테이블명] (약 [건수] 행)
- 기존 복합 인덱스 목록:
  * [인덱스명]: ([컬럼1], [컬럼2])

[슬로우 쿼리]
```sql
[여기에 쿼리 붙여넣기]
```

[실행 계획 출력]
```text
[EXPLAIN ANALYZE 결과 붙여넣기]
```

[도출 요구사항]
1. 실제 디스크 I/O를 유발하는 핵심 병목 노드 분석 (Seq Scan, Filesort, Temp Spill 여부)
2. 무중단(Non-blocking) 인덱스 생성 DDL 제안 (컬럼 순서 및 커버링 INCLUDE 반영)
3. 재작성된 고성능 SQL 및 예상 지연시간 단축치 제시

6. 프롬프트 활용 팁 & 주의사항

  • 1. ANALYZE 갱신 여부 확인: 통계 데이터가 낡아 있으면 옵티마이저가 엉뚱한 실행 계획을 짭니다. 대규모 데이터 변경 후에는 PostgreSQL ANALYZE tablename;, MySQL ANALYZE TABLE tablename;을 먼저 실행한 뒤 프롬프트에 플랜을 넣으십시오.
  • 2. 민감 정보 마스킹: WHERE 절에 고객 주민번호, 계좌번호, 이메일 리터럴이 들어가 있다면 :user_email 형태의 바인드 변수로 치환하여 프롬프트에 입력하십시오.
  • 3. 무중단 옵션 필수 확인: 프로덕션 테이블에 인덱스를 걸 때 PostgreSQL은 CONCURRENTLY, MySQL은 ALGORITHM=INPLACE, LOCK=NONE이 없으면 트래픽이 몰리는 순간 서비스 전체가 멈춥니다. AI에게 항상 무중단 DDL 키워드를 강제하십시오.
  • 4. 인덱스는 다다익선이 아님: 인덱스가 1개 추가될 때마다 INSERT/UPDATE/DELETE 시 B-Tree 분할(Page Split) 비용이 누적됩니다. 기존에 존재하던 중복/접두사 인덱스를 반드시 정리(Drop Unused Indexes)하십시오.

댓글 쓰기

다음 이전