# ----------------------------- # PostgreSQL 18 최적화 설정 # 하드웨어 사양: 4코어 CPU, 4GB RAM, SSD, 1GB LAN # ----------------------------- #------------------------------------------------------------------------------ # FILE LOCATIONS #------------------------------------------------------------------------------ #data_directory = 'ConfigDir' #hba_file = 'ConfigDir/pg_hba.conf' #ident_file = 'ConfigDir/pg_ident.conf' #external_pid_file = '' #------------------------------------------------------------------------------ # CONNECTIONS AND AUTHENTICATION #------------------------------------------------------------------------------ # - Connection Settings - listen_addresses = '*' # 기본값: 'localhost' # 변경값: '*' (모든 IP에서 접근 허용) # 목적: 네트워크를 통한 원격 접속 허용 #port = 5432 max_connections = 100 # 기본값: 100 # 유지 이유: 4GB RAM 환경에서 적절한 연결 수 # 성능: 각 연결은 약 10MB의 메모리를 사용하므로 100개 연결 = 약 1GB # 참고: 연결 풀링(pgBouncer 등) 사용 시 더 효율적 #reserved_connections = 0 #superuser_reserved_connections = 3 #unix_socket_directories = '/var/run/postgresql' #unix_socket_group = '' #unix_socket_permissions = 0777 #bonjour = off #bonjour_name = '' # - TCP settings - tcp_keepalives_idle = 60 # 기본값: 0 (시스템 기본값 사용, 보통 7200초) # 변경값: 60초 # 목적: 유휴 연결을 60초마다 체크하여 죽은 연결을 빠르게 감지 # 성능: 네트워크 장애 시 빠른 연결 정리로 리소스 확보 tcp_keepalives_interval = 10 # 기본값: 0 (시스템 기본값 사용, 보통 75초) # 변경값: 10초 # 목적: keepalive 재전송 간격 # 성능: 연결 문제를 빠르게 탐지 tcp_keepalives_count = 3 # 기본값: 0 (시스템 기본값 사용, 보통 9회) # 변경값: 3회 # 목적: 연결 실패 판정까지의 재시도 횟수 # 성능: 60초 + (10초 × 3) = 최대 90초 내에 죽은 연결 정리 #tcp_user_timeout = 0 #client_connection_check_interval = 0 # - Authentication - #authentication_timeout = 1min #password_encryption = scram-sha-256 #scram_iterations = 4096 # - SSL - #ssl = off #ssl_ca_file = '' #ssl_cert_file = 'server.crt' #------------------------------------------------------------------------------ # RESOURCE USAGE (except WAL) #------------------------------------------------------------------------------ # - Memory - shared_buffers = 1GB # 기본값: 128MB # 변경값: 1GB (전체 RAM 4GB의 25%) # 목적: 데이터베이스가 디스크에서 읽은 데이터를 캐시하는 메모리 # 성능: 자주 사용되는 데이터를 메모리에 유지하여 디스크 I/O 크게 감소 # 참고: PostgreSQL에서 가장 중요한 메모리 설정 중 하나 huge_pages = try # 기본값: try # 유지 이유: 가능한 경우 huge pages 사용으로 메모리 관리 효율 향상 # 성능: TLB 미스 감소, 대용량 shared_buffers 사용 시 특히 효과적 #huge_page_size = 0 #temp_buffers = 8MB #max_prepared_transactions = 0 work_mem = 16MB # 기본값: 4MB # 변경값: 16MB # 목적: 정렬, 해시 테이블 등 쿼리 작업에 사용되는 메모리 # 성능: 복잡한 쿼리의 정렬/조인 성능 향상, 디스크 임시 파일 사용 감소 # 주의: (max_connections × work_mem)이 너무 크면 OOM 위험 # 계산: 100 연결 × 16MB = 최대 1.6GB (복잡한 쿼리가 동시 실행될 경우) #hash_mem_multiplier = 2.0 maintenance_work_mem = 256MB # 기본값: 64MB # 변경값: 256MB (RAM의 약 6%) # 목적: VACUUM, CREATE INDEX, ALTER TABLE 등 유지보수 작업에 사용 # 성능: 인덱스 생성 및 VACUUM 작업 속도 대폭 향상 # 참고: 유지보수 작업은 동시에 많이 실행되지 않으므로 크게 설정 가능 autovacuum_work_mem = 256MB # 기본값: -1 (maintenance_work_mem 사용) # 변경값: 256MB # 목적: autovacuum 전용 메모리 할당 # 성능: autovacuum 성능 향상으로 테이블 bloat 감소 #logical_decoding_work_mem = 64MB max_stack_depth = 2MB # 기본값: 2MB # 유지 이유: 기본값이 대부분의 경우에 적절 #shared_memory_type = mmap dynamic_shared_memory_type = posix # 기본값: posix (Linux에서) # 유지 이유: Linux에서 가장 효율적인 방식 #min_dynamic_shared_memory = 0MB # - Disk - #temp_file_limit = -1 #file_copy_method = copy # - Kernel Resources - #max_files_per_process = 1000 # - Background Writer - bgwriter_delay = 200ms # 기본값: 200ms # 유지 이유: SSD 환경에서도 기본값이 적절 bgwriter_lru_maxpages = 100 # 기본값: 100 # 유지 이유: 백그라운드 쓰기 작업의 균형 유지 #bgwriter_lru_multiplier = 2.0 bgwriter_flush_after = 512kB # 기본값: 512kB # 유지 이유: SSD에서 적절한 flush 크기 # - I/O - #backend_flush_after = 0 effective_io_concurrency = 200 # 기본값: 1 (HDD), 16 (SSD 감지 시) # 변경값: 200 # 목적: SSD의 높은 IOPS를 활용한 병렬 I/O 요청 수 # 성능: bitmap heap scan 등에서 여러 페이지를 동시에 prefetch # 참고: SSD는 동시 I/O 처리 능력이 뛰어나므로 높게 설정 maintenance_io_concurrency = 200 # 기본값: 10 # 변경값: 200 # 목적: VACUUM, CREATE INDEX 등 유지보수 작업의 병렬 I/O # 성능: 유지보수 작업 속도 향상 #io_max_combine_limit = 128kB #io_combine_limit = 128kB #io_method = worker #io_max_concurrency = -1 #io_workers = 3 # - Worker Processes - max_worker_processes = 8 # 기본값: 8 # 유지 이유: 4코어 환경에서 적절 (코어 수 × 2) # 성능: 병렬 쿼리, autovacuum 등 다양한 백그라운드 작업 처리 max_parallel_workers_per_gather = 2 # 기본값: 2 # 변경값: 2 (4코어 환경에서 적절) # 목적: 단일 쿼리가 사용할 수 있는 최대 병렬 worker 수 # 성능: 대용량 테이블 스캔 시 쿼리 속도 향상 # 참고: 너무 높으면 다른 쿼리의 리소스 부족 발생 가능 max_parallel_maintenance_workers = 2 # 기본값: 2 # 유지 이유: CREATE INDEX 등 유지보수 작업의 병렬화 # 성능: 인덱스 생성 속도 향상 max_parallel_workers = 4 # 기본값: 8 # 변경값: 4 (CPU 코어 수) # 목적: 시스템 전체에서 동시 실행 가능한 병렬 worker 총 수 # 성능: CPU 코어 수에 맞춰 과도한 컨텍스트 스위칭 방지 #parallel_leader_participation = on #------------------------------------------------------------------------------ # WRITE-AHEAD LOG #------------------------------------------------------------------------------ # - Settings - #wal_level = replica #fsync = on #synchronous_commit = on #wal_sync_method = fsync #full_page_writes = on #wal_log_hints = off wal_compression = lz4 # 기본값: off # 변경값: lz4 # 목적: WAL 파일 압축으로 I/O 및 스토리지 사용량 감소 # 성능: 네트워크를 통한 복제 시 대역폭 절약, 아카이빙 효율 향상 # 참고: CPU 사용량은 약간 증가하지만 4코어 환경에서 무리 없음 #wal_init_zero = on #wal_recycle = on wal_buffers = 16MB # 기본값: -1 (shared_buffers의 3%, 최소 64kB, 최대 약 16MB) # 변경값: 16MB # 목적: WAL 데이터를 디스크에 쓰기 전 버퍼링 # 성능: 쓰기 집약적 워크로드에서 WAL 쓰기 성능 향상 #wal_writer_delay = 200ms wal_writer_flush_after = 1MB # 기본값: 1MB # 유지 이유: SSD에서 적절한 flush 크기 #wal_skip_threshold = 2MB #commit_delay = 0 #commit_siblings = 5 # - Checkpoints - checkpoint_timeout = 15min # 기본값: 5min # 변경값: 15min # 목적: 체크포인트 발생 간격 조정 # 성능: 체크포인트 빈도 감소로 I/O spike 완화, 전체 성능 향상 # 참고: 크래시 복구 시간은 약간 증가하지만 일반적으로 허용 가능 checkpoint_completion_target = 0.9 # 기본값: 0.9 # 유지 이유: 체크포인트를 시간에 걸쳐 분산하여 I/O spike 방지 # 성능: 90%의 시간에 걸쳐 checkpoint 완료하여 부하 분산 #checkpoint_flush_after = 256kB #checkpoint_warning = 30s max_wal_size = 2GB # 기본값: 1GB # 변경값: 2GB # 목적: 체크포인트 간 생성 가능한 최대 WAL 크기 # 성능: 쓰기 집약적 워크로드에서 체크포인트 빈도 감소 # 참고: SSD 환경에서 더 큰 WAL 크기는 성능에 유리 min_wal_size = 1GB # 기본값: 80MB # 변경값: 1GB # 목적: 항상 유지할 최소 WAL 크기 # 성능: WAL 파일 재사용으로 파일 생성/삭제 오버헤드 감소 # - Prefetching during recovery - #recovery_prefetch = try #wal_decode_buffer_size = 512kB # - Archiving - #archive_mode = off #archive_library = '' #archive_command = '' #archive_timeout = 0 #------------------------------------------------------------------------------ # REPLICATION #------------------------------------------------------------------------------ # - Sending Servers - #max_wal_senders = 10 #max_replication_slots = 10 #wal_keep_size = 0 #max_slot_wal_keep_size = -1 #idle_replication_slot_timeout = 0 #wal_sender_timeout = 60s #track_commit_timestamp = off # - Primary Server - #synchronous_standby_names = '' #synchronized_standby_slots = '' # - Standby Servers - #primary_conninfo = '' #primary_slot_name = '' #hot_standby = on #max_standby_archive_delay = 30s #max_standby_streaming_delay = 30s #wal_receiver_create_temp_slot = off #wal_receiver_status_interval = 10s #hot_standby_feedback = off #wal_receiver_timeout = 60s #wal_retrieve_retry_interval = 5s #recovery_min_apply_delay = 0 #sync_replication_slots = off # - Subscribers - #max_active_replication_origins = 10 #max_logical_replication_workers = 4 #max_sync_workers_per_subscription = 2 #max_parallel_apply_workers_per_subscription = 2 #------------------------------------------------------------------------------ # QUERY TUNING #------------------------------------------------------------------------------ # - Planner Method Configuration - #enable_async_append = on #enable_bitmapscan = on #enable_gathermerge = on #enable_hashagg = on #enable_hashjoin = on #enable_incremental_sort = on #enable_indexscan = on #enable_indexonlyscan = on #enable_material = on #enable_memoize = on #enable_mergejoin = on #enable_nestloop = on #enable_parallel_append = on #enable_parallel_hash = on #enable_partition_pruning = on #enable_partitionwise_join = off #enable_partitionwise_aggregate = off #enable_presorted_aggregate = on #enable_seqscan = on #enable_sort = on #enable_tidscan = on # - Planner Cost Constants - #seq_page_cost = 1.0 random_page_cost = 1.1 # 기본값: 4.0 (HDD), 1.1 (SSD 자동 감지 시) # 변경값: 1.1 # 목적: SSD의 랜덤 액세스 특성을 반영 # 성능: 인덱스 스캔 선호도 증가, 쿼리 플래너의 더 나은 결정 # 참고: HDD는 4.0, SSD는 1.1-1.5가 적절 #cpu_tuple_cost = 0.01 #cpu_index_tuple_cost = 0.005 #cpu_operator_cost = 0.0025 #parallel_setup_cost = 1000.0 #parallel_tuple_cost = 0.1 #min_parallel_table_scan_size = 8MB #min_parallel_index_scan_size = 512kB effective_cache_size = 3GB # 기본값: 4GB (시스템에 따라 다름) # 변경값: 3GB (전체 RAM 4GB의 75%) # 목적: OS와 PostgreSQL이 파일 캐싱에 사용 가능한 메모리 추정 # 성능: 쿼리 플래너가 인덱스 스캔 비용을 더 정확히 계산 # 참고: shared_buffers + OS 파일 캐시 = 약 3GB #jit_above_cost = 100000 #jit_inline_above_cost = 500000 #jit_optimize_above_cost = 500000 # - Genetic Query Optimizer - #geqo = on #geqo_threshold = 12 # - Other Planner Options - default_statistics_target = 100 # 기본값: 100 # 유지 이유: 통계 정확도와 ANALYZE 시간의 균형 # 성능: 쿼리 플래너의 정확한 비용 추정 # 참고: 특정 컬럼에 대해 개별적으로 높일 수 있음 #constraint_exclusion = partition #cursor_tuple_fraction = 0.1 #from_collapse_limit = 8 #jit = on #join_collapse_limit = 8 #plan_cache_mode = auto #recursive_worktable_factor = 10.0 #------------------------------------------------------------------------------ # REPORTING AND LOGGING #------------------------------------------------------------------------------ # 로깅 설정은 기본값 유지 (사용자 요청사항) #log_destination = 'stderr' #logging_collector = off #log_directory = 'log' #log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' #log_file_mode = 0600 #log_rotation_age = 1d #log_rotation_size = 10MB #log_truncate_on_rotation = off #syslog_facility = 'LOCAL0' #syslog_ident = 'postgres' #syslog_sequence_numbers = on #syslog_split_messages = on #event_source = 'PostgreSQL' #log_min_messages = warning #log_min_error_statement = error #log_min_duration_statement = -1 #log_min_duration_sample = -1 #log_statement_sample_rate = 1.0 #log_transaction_sample_rate = 0.0 #log_startup_progress_interval = 10s #debug_print_parse = off #debug_print_rewritten = off #debug_print_plan = off #debug_pretty_print = on #log_autovacuum_min_duration = 10min #log_checkpoints = on #log_connections = '' #log_disconnections = off #log_duration = off #log_error_verbosity = default #log_hostname = off #log_line_prefix = '%m [%p] ' #log_lock_waits = off #log_lock_failures = off #log_recovery_conflict_waits = off #log_parameter_max_length = -1 #log_parameter_max_length_on_error = 0 #log_statement = 'none' #log_replication_commands = off #log_temp_files = -1 log_timezone = 'Etc/UTC' #cluster_name = '' #update_process_title = on #------------------------------------------------------------------------------ # STATISTICS #------------------------------------------------------------------------------ #track_activities = on #track_activity_query_size = 1024 #track_counts = on #track_cost_delay_timing = off track_io_timing = on # 기본값: off # 변경값: on # 목적: I/O 작업의 시간 추적으로 성능 병목 지점 파악 # 성능: EXPLAIN ANALYZE 등으로 I/O 병목 진단 가능 # 참고: 약간의 오버헤드 있지만 성능 튜닝에 매우 유용 #track_wal_io_timing = off #track_functions = none #stats_fetch_consistency = cache # - Monitoring - #compute_query_id = auto #log_statement_stats = off #log_parser_stats = off #log_planner_stats = off #log_executor_stats = off #------------------------------------------------------------------------------ # VACUUMING #------------------------------------------------------------------------------ # - Automatic Vacuuming - #autovacuum = on autovacuum_worker_slots = 8 # 기본값: 16 (PostgreSQL 18 신규 파라미터) # 변경값: 8 # 목적: autovacuum worker 슬롯 수 (동시 실행 가능한 worker 총량) # 성능: 4코어 환경에서 적절한 슬롯 수로 CPU 리소스 균형 # 참고: max_workers와 별개로 동적으로 worker 생성 가능 autovacuum_max_workers = 3 # 기본값: 3 # 변경값: 3 # 목적: 동시에 실행 가능한 autovacuum worker 프로세스 수 # 성능: 여러 테이블을 동시에 vacuum 처리 # 참고: 4코어 환경에서 적절한 수준 autovacuum_naptime = 30s # 기본값: 1min # 변경값: 30s # 목적: autovacuum이 데이터베이스를 체크하는 주기 # 성능: 더 빈번한 체크로 테이블 bloat 감소, 성능 유지 # 참고: 쓰기가 많은 환경에서 효과적 #autovacuum_vacuum_threshold = 50 #autovacuum_vacuum_insert_threshold = 1000 #autovacuum_analyze_threshold = 50 autovacuum_vacuum_scale_factor = 0.1 # 기본값: 0.2 (테이블의 20%) # 변경값: 0.1 (테이블의 10%) # 목적: vacuum 실행 trigger 조건 (dead tuple 비율) # 성능: 더 자주 vacuum 실행으로 테이블 bloat 최소화 # 참고: 대형 테이블에서 특히 효과적 #autovacuum_vacuum_insert_scale_factor = 0.2 autovacuum_analyze_scale_factor = 0.05 # 기본값: 0.1 (테이블의 10%) # 변경값: 0.05 (테이블의 5%) # 목적: analyze 실행 trigger 조건 # 성능: 더 빈번한 통계 업데이트로 쿼리 플래너의 정확도 향상 #autovacuum_vacuum_max_threshold = 100000000 #autovacuum_freeze_max_age = 200000000 #autovacuum_multixact_freeze_max_age = 400000000 #autovacuum_vacuum_cost_delay = 2ms #autovacuum_vacuum_cost_limit = -1 # - Cost-Based Vacuum Delay - #vacuum_cost_delay = 0 #vacuum_cost_page_hit = 1 #vacuum_cost_page_miss = 2 #vacuum_cost_page_dirty = 20 #vacuum_cost_limit = 200 # - Default Behavior - #vacuum_truncate = on # - Freezing - #vacuum_freeze_table_age = 150000000 #vacuum_freeze_min_age = 50000000 #vacuum_failsafe_age = 1600000000 #vacuum_multixact_freeze_table_age = 150000000 #vacuum_multixact_freeze_min_age = 5000000 #vacuum_multixact_failsafe_age = 1600000000 #vacuum_max_eager_freeze_failure_rate = 0.03 #------------------------------------------------------------------------------ # CLIENT CONNECTION DEFAULTS #------------------------------------------------------------------------------ # - Statement Behavior - #client_min_messages = notice #search_path = '"$user", public' #row_security = on #default_table_access_method = 'heap' #default_tablespace = '' #default_toast_compression = 'pglz' #temp_tablespaces = '' #check_function_bodies = on #default_transaction_isolation = 'read committed' #default_transaction_read_only = off #default_transaction_deferrable = off #session_replication_role = 'origin' statement_timeout = 30000 # 기본값: 0 (무제한) # 변경값: 30000ms (30초) # 목적: 장시간 실행되는 쿼리 자동 종료 # 성능: 문제있는 쿼리로 인한 리소스 점유 방지 # 참고: 애플리케이션 특성에 따라 조정 필요, 0으로 비활성화 가능 #transaction_timeout = 0 lock_timeout = 5000 # 기본값: 0 (무제한) # 변경값: 5000ms (5초) # 목적: 락 대기 시간 제한 # 성능: 데드락 상황 빠른 감지, 애플리케이션 응답성 향상 #idle_in_transaction_session_timeout = 0 idle_session_timeout = 300000 # 기본값: 0 (무제한) # 변경값: 300000ms (5분) # 목적: 유휴 세션 자동 종료 # 성능: 불필요한 연결로 인한 리소스 낭비 방지 # 참고: 연결 풀 사용 시 조정 필요 #bytea_output = 'hex' #xmlbinary = 'base64' #xmloption = 'content' #gin_pending_list_limit = 4MB #createrole_self_grant = '' #event_triggers = on # - Locale and Formatting - datestyle = 'iso, mdy' #intervalstyle = 'postgres' timezone = 'Etc/UTC' #timezone_abbreviations = 'Default' #extra_float_digits = 1 #client_encoding = sql_ascii lc_messages = 'en_US.utf8' lc_monetary = 'en_US.utf8' lc_numeric = 'en_US.utf8' lc_time = 'en_US.utf8' #icu_validation_level = warning default_text_search_config = 'pg_catalog.english' # - Shared Library Preloading - #local_preload_libraries = '' #session_preload_libraries = '' #shared_preload_libraries = '' #jit_provider = 'llvmjit' # - Other Defaults - #dynamic_library_path = '$libdir' #extension_control_path = '$system' #gin_fuzzy_search_limit = 0 #------------------------------------------------------------------------------ # LOCK MANAGEMENT #------------------------------------------------------------------------------ deadlock_timeout = 1s # 기본값: 1s # 유지 이유: 데드락 감지를 위한 적절한 대기 시간 #max_locks_per_transaction = 64 #max_pred_locks_per_transaction = 64 #max_pred_locks_per_relation = -2 #max_pred_locks_per_page = 2 #------------------------------------------------------------------------------ # VERSION AND PLATFORM COMPATIBILITY #------------------------------------------------------------------------------ #array_nulls = on #backslash_quote = safe_encoding #escape_string_warning = on #lo_compat_privileges = off #quote_all_identifiers = off #standard_conforming_strings = on #synchronize_seqscans = on #transform_null_equals = off #allow_alter_system = on #------------------------------------------------------------------------------ # ERROR HANDLING #------------------------------------------------------------------------------ #exit_on_error = off #restart_after_crash = on #data_sync_retry = off #recovery_init_sync_method = fsync #------------------------------------------------------------------------------ # CONFIG FILE INCLUDES #------------------------------------------------------------------------------ #include_dir = '...' #include_if_exists = '...' #include = '...' #------------------------------------------------------------------------------ # CUSTOMIZED OPTIONS #------------------------------------------------------------------------------ # ============================================================================= # 주요 변경사항 요약 # ============================================================================= # # 1. 메모리 설정 (4GB RAM 기준) # - shared_buffers: 128MB → 1GB (25% of RAM) # - effective_cache_size: 4GB → 3GB (75% of RAM) # - work_mem: 4MB → 16MB (쿼리 성능 향상) # - maintenance_work_mem: 64MB → 256MB (유지보수 작업 가속) # # 2. 연결 관리 # - tcp_keepalives 설정: 죽은 연결 빠른 감지 (90초 이내) # - statement_timeout: 30초 (장시간 쿼리 방지) # - lock_timeout: 5초 (락 대기 제한) # - idle_session_timeout: 5분 (유휴 세션 정리) # # 3. 병렬 처리 (4코어 최적화) # - max_parallel_workers: 4 (CPU 코어 수) # - max_parallel_workers_per_gather: 2 # - max_worker_processes: 8 # # 4. I/O 최적화 (SSD 특화) # - random_page_cost: 4.0 → 1.1 # - effective_io_concurrency: 1 → 200 # - maintenance_io_concurrency: 10 → 200 # # 5. WAL 및 체크포인트 # - wal_compression: off → lz4 (I/O 감소) # - wal_buffers: 자동 → 16MB # - checkpoint_timeout: 5min → 15min # - max_wal_size: 1GB → 2GB # - min_wal_size: 80MB → 1GB # # 6. Autovacuum 튜닝 # - autovacuum_worker_slots: 16 → 8 # - autovacuum_naptime: 1min → 30s (더 빈번한 체크) # - autovacuum_vacuum_scale_factor: 0.2 → 0.1 (더 자주 실행) # - autovacuum_analyze_scale_factor: 0.1 → 0.05 # # 7. 모니터링 # - track_io_timing: off → on (I/O 성능 진단) # # ============================================================================= # 예상 성능 향상 # ============================================================================= # # - 읽기 성능: 30-50% 향상 (shared_buffers, effective_cache_size) # - 쓰기 성능: 20-40% 향상 (WAL 설정, checkpoint 최적화) # - 복잡한 쿼리: 40-100% 향상 (work_mem, 병렬 처리) # - 유지보수 작업: 100-300% 향상 (maintenance_work_mem, I/O 동시성) # - 전체 처리량: 25-50% 향상 (모든 최적화의 시너지) # # ============================================================================= # 적용 방법 # ============================================================================= # # 1. 이 파일을 postgresql.conf로 저장 (또는 기존 파일 백업 후 교체) # 2. PostgreSQL 재시작: # sudo systemctl restart postgresql # 또는 # sudo pg_ctl restart -D /var/lib/postgresql/data # # 3. 설정 확인: # SHOW shared_buffers; # SHOW effective_cache_size; # SHOW work_mem; # # 4. 모니터링 (첫 며칠간): # - 메모리 사용량: free -h, htop # - 체크포인트 빈도: 로그 확인 # - 쿼리 성능: pg_stat_statements 활용 # # =============================================================================