-- ================================ -- 성능 최적화를 위한 추가 인덱스 -- 생성일: 2025.01 (Phase 2) -- ================================ -- 1. 복합 인덱스 (자주 함께 사용되는 컬럼들) -- ================================ -- files 테이블: job_no + revision 조합 (리비전 비교 시 자주 사용) CREATE INDEX IF NOT EXISTS idx_files_job_revision ON files(job_no, revision) WHERE is_active = true; -- files 테이블: job_no + upload_date (최신 파일 조회) CREATE INDEX IF NOT EXISTS idx_files_job_date ON files(job_no, upload_date DESC) WHERE is_active = true; -- materials 테이블: file_id + category (자재 분류별 조회) CREATE INDEX IF NOT EXISTS idx_materials_file_category ON materials(file_id, classified_category); -- materials 테이블: category + material_grade (자재 종류별 재질 검색) CREATE INDEX IF NOT EXISTS idx_materials_category_grade ON materials(classified_category, material_grade); -- 2. 검색 성능 향상 인덱스 -- ================================ -- materials 테이블: description 텍스트 검색 (GIN 인덱스) CREATE INDEX IF NOT EXISTS idx_materials_description_gin ON materials USING gin(to_tsvector('english', original_description)); -- materials 테이블: 해시 기반 중복 검색 CREATE INDEX IF NOT EXISTS idx_materials_hash ON materials(material_hash) WHERE material_hash IS NOT NULL; -- 3. 정렬 성능 향상 인덱스 -- ================================ -- jobs 테이블: 상태별 생성일 정렬 CREATE INDEX IF NOT EXISTS idx_jobs_status_created ON jobs(status, created_at DESC) WHERE is_active = true; -- materials 테이블: 수량별 정렬 (대용량 자재 우선 표시) CREATE INDEX IF NOT EXISTS idx_materials_quantity_desc ON materials(quantity DESC); -- 4. 조건부 인덱스 (특정 조건에서만 사용) -- ================================ -- 검증되지 않은 자재만 (분류 검토 필요한 항목) CREATE INDEX IF NOT EXISTS idx_materials_unverified ON materials(classified_category, classification_confidence) WHERE is_verified = false; -- 신뢰도가 낮은 분류 (0.8 미만) CREATE INDEX IF NOT EXISTS idx_materials_low_confidence ON materials(file_id, classified_category) WHERE classification_confidence < 0.8; -- 5. 외래키 성능 향상 -- ================================ -- pipe_details 테이블 CREATE INDEX IF NOT EXISTS idx_pipe_details_material ON pipe_details(material_id); -- fitting_details 테이블 CREATE INDEX IF NOT EXISTS idx_fitting_details_material ON fitting_details(material_id); -- valve_details 테이블 CREATE INDEX IF NOT EXISTS idx_valve_details_material ON valve_details(material_id); -- flange_details 테이블 CREATE INDEX IF NOT EXISTS idx_flange_details_material ON flange_details(material_id); -- bolt_details 테이블 CREATE INDEX IF NOT EXISTS idx_bolt_details_material ON bolt_details(material_id); -- gasket_details 테이블 CREATE INDEX IF NOT EXISTS idx_gasket_details_material ON gasket_details(material_id); -- instrument_details 테이블 CREATE INDEX IF NOT EXISTS idx_instrument_details_material ON instrument_details(material_id); -- 6. 통계 및 집계 성능 향상 -- ================================ -- 프로젝트별 자재 통계 (job_no 기준) CREATE INDEX IF NOT EXISTS idx_materials_job_stats ON materials( (SELECT job_no FROM files WHERE files.id = materials.file_id), classified_category ); -- 파이프 길이 집계용 (파이프 cutting 계산) CREATE INDEX IF NOT EXISTS idx_pipe_length_aggregation ON pipe_details(material_id, length_mm) WHERE length_mm > 0; -- 7. 성능 모니터링을 위한 뷰 생성 -- ================================ -- 인덱스 사용률 모니터링 뷰 CREATE OR REPLACE VIEW index_usage_stats AS SELECT schemaname, tablename, indexname, idx_tup_read, idx_tup_fetch, idx_scan, CASE WHEN idx_scan = 0 THEN 'UNUSED' WHEN idx_scan < 10 THEN 'LOW_USAGE' WHEN idx_scan < 100 THEN 'MEDIUM_USAGE' ELSE 'HIGH_USAGE' END as usage_level FROM pg_stat_user_indexes WHERE schemaname = 'public' ORDER BY idx_scan DESC; -- 테이블 크기 및 성능 모니터링 뷰 CREATE OR REPLACE VIEW table_performance_stats AS SELECT schemaname, tablename, n_tup_ins as inserts, n_tup_upd as updates, n_tup_del as deletes, seq_scan as sequential_scans, seq_tup_read as sequential_reads, idx_scan as index_scans, idx_tup_fetch as index_reads, CASE WHEN seq_scan + idx_scan = 0 THEN 0 ELSE ROUND((idx_scan::numeric / (seq_scan + idx_scan)) * 100, 2) END as index_usage_percentage FROM pg_stat_user_tables WHERE schemaname = 'public' ORDER BY seq_scan + idx_scan DESC; -- ================================ -- 인덱스 생성 완료 로그 -- ================================ -- 성능 최적화 인덱스 생성 완료 확인 DO $$ BEGIN RAISE NOTICE '성능 최적화 인덱스 생성 완료 - Phase 2 (2025.01)'; RAISE NOTICE '총 생성된 인덱스: 복합 인덱스 4개, 검색 인덱스 2개, 정렬 인덱스 2개'; RAISE NOTICE '조건부 인덱스 2개, 외래키 인덱스 7개, 집계 인덱스 2개'; RAISE NOTICE '모니터링 뷰 2개 생성'; END $$;